Set-up

rm(list = ls())
library(dplyr)
library(wesanderson)
library(GillespieSSA)
library(tidyverse)

Model Parameter estimation

Agta Hunter-Gatherer Demography

Information regarding births, deaths and population size were obtain from a study conducted by Headland et al., (2011). Authors conducted a census-like survey of the

agta_demo <- read.csv("AgtaPopDynamics_Headland2007.csv")

ggplot(agta_demo, aes(x=Year)) +
  geom_line(aes(y=PopSize), colour = wes_palettes$Darjeeling1[1]) +
  geom_line(aes(y=Births), colour = wes_palettes$Darjeeling1[2]) +
  geom_line(aes(y=Deaths), colour = wes_palettes$Darjeeling1[3]) +
  theme_bw()

Population Size

hist(agta_demo$PopSize)

summary(agta_demo$PopSize)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  133.0   177.0   213.0   211.4   228.0   295.0 

Births

hist(agta_demo$Births)

summary(agta_demo$Births)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
   4.00    8.00   10.00   10.33   12.25   15.00       1 

Deaths

hist(agta_demo$Deaths)

summary(agta_demo$Deaths)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
  2.000   5.000   7.000   7.683  10.000  23.000       1 

Birth/Death rate per person per day

agta_demo <- agta_demo %>%
  mutate(Birth_rate = Births/(Female*2),
         Birth_rate_daily = (1 + Birth_rate) ^ (1/365) - 1,
         Death_rate = (Deaths/PopSize),
         Death_rate_daily = (1 + Death_rate) ^ (1/365) - 1,
         PopChange = (diff = PopSize - lag(PopSize, default = first(PopSize))),
         PopChange_rate = abs(PopChange)/PopSize,
         PopChange_rate_daily = (1 + PopChange_rate) ^ (1/365) - 1)
head(agta_demo)


hist(agta_demo$Birth_rate)

hist(agta_demo$Death_rate)


ggplot(agta_demo, aes(x=Year)) +
  geom_line(aes(y=Birth_rate), colour = wes_palettes$Darjeeling1[2]) +
  geom_line(aes(y=Death_rate), colour = wes_palettes$Darjeeling1[3]) +
  theme_bw()


demo_sum <- agta_demo %>%
  select(PopSize, Birth_rate, Birth_rate_daily, Death_rate, Death_rate_daily, PopChange_rate, PopChange_rate_daily) %>%
    summarise(across(
    .cols = is.numeric, 
    .fns = list(Mean = mean, SD = sd), na.rm = TRUE, 
    .names = "{col}_{fn}"
    ))
demo_sum 

demo_sum <- as.list(demo_sum)

Agta Band Size

# Import Camp data from Mark Dyble
camps.data <- read_csv("camps.csv")
New names:Rows: 15 Columns: 9── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (1): camp_name
dbl (8): ...1, camp_total, camp_adult_men, camp_adult_women, camp_all_r, camp_adult_r, forage, turnover
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(camps.data)
# Explore camp size
hist(camps.data$camp_total)


camp.size <- camps.data %>%
  summarise(mean = mean(camp_total),
            sd = sd(camp_total),
            min = min(camp_total),
            max = max(camp_total),
            var = var(camp_total))
camp.size

Single Population Model

Set-up

N
[1] 96

Define functions to calculate R0 and expected number of susceptibles at equilibrium, and critical community size (Diekmann et al., 2012).

 R0 <- function(parms) {
   (parms$sigma/(parms$sigma + parms$mu)) * (parms$beta/parms$gamma + parms$mu + parms$alpha)
 } 
  
EIE <- function(R0, parms) {
  y = ((R0 - 1) * parms$omega) / (parms$gamma * R0)
  return(y)
}

CCS <- function(epsilon, R0) {
  y = 1/((epsilon^2)*((1-(1/R0))^2))
  return(y)
}

Single Population Model


# Calculate R0, expected number of infecteds at equilibrium, magnitude of oscillation and CCS
R0_single <- R0(parms)
R0_single
[1] 2.998695
EIE_single <- EIE(R0_single, parms) # proportion of expected infecteds at equilibrium
EIE_single
[1] 0.03332608
expexted_infecteds <- EIE_single*N # number of expected infecteds at equilibrium
expexted_infecteds
[1] 3.199304
sqrt(N) # magnitude of oscilations
[1] 9.797959
epsilon <- (5.7/365)/23 # duration of infection in years divided by avg life expectancy 
CCS_single <- CCS(epsilon, R0_single) # Average life expectancy as per Kaplan (crude)
CCS_single
[1] 4882736
# Run simulations with the Direct method
set.seed(21)
out <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
) 



## Extra Plots
plot_data <- out$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

single_plot <- ggplot(data = plot_data, aes(x=t, y=count, colour=state))+
  geom_line(alpha=0.8)+
  labs(x="Time (Days)",
       y="Number of Individuals", 
       colour="State")+
  geom_hline(yintercept = expexted_infecteds, linetype = 'dashed') +
  theme_bw()

single_plot

ggsave(filename = "single_plot.pdf", 
       plot = single_plot,
       device = "pdf",
       width = 7, 
       height = 3,
       path = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models")

plot_data %>%
  filter(state == "I") %>%
  slice_max(count)
parms
$beta
[1] 0.6

$sigma
[1] 0.175

$gamma
[1] 0.2

$omega
[1] 0.01

$mu
[1] 0.0001428636

$alpha
[1] 0.001
# Summary table of endpoint data
sim_output <- sim_output %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output

# Make Summary Table of output
sim_summary <- sim_output %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100, 
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/100)
sim_summary

Varying waining immunity

0 Days

#Collect parameters
parms_0 <- parms
parms_0$omega <- 0


# Run simulations with the Direct method
set.seed(4)
out_0 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_0,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_0 <- out_0$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_0 <- ggplot(data = plot_data_0, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_0

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_0 <- list()
sim_list_0 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_0 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_0,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_0 <- out_100_0$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_0[[i]] <- sim_data_0
}

sim_output_0 <- bind_rows(sim_list_0)
# Summary table of endpoint data
sim_output_0 <- sim_output_0 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_0

# Make Summary Table of output
sim_summary_0 <- sim_output_0 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100) %>%
  mutate(omega = 0)
sim_summary_0

1 Days

#Collect parameters
parms_1 <- parms
parms_1$omega <- 1


# Run simulations with the Direct method
set.seed(4)
out_1 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_1,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_1 <- out_1$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_1 <- ggplot(data = plot_data_1, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_1

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_1 <- list()
sim_list_1 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_1 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_1,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_1 <- out_100_1$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_1[[i]] <- sim_data_1
}

sim_output_1 <- bind_rows(sim_list_1)
# Summary table of endpoint data
sim_output_1 <- sim_output_1 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_1

# Make Summary Table of output
sim_summary_1 <- sim_output_1 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1)
sim_summary_1

3 Days

#Collect parameters
parms_3 <- parms
parms_3$omega <- 1/3


# Run simulations with the Direct method
set.seed(4)
out_3 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_3,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3 <- out_3$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3 <- ggplot(data = plot_data_3, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3 <- list()
sim_list_3 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_3 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_3,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3 <- out_100_3$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_3[[i]] <- sim_data_3
}

sim_output_3 <- bind_rows(sim_list_3)
# Summary table of endpoint data
sim_output_3 <- sim_output_3 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3

# Make Summary Table of output
sim_summary_3 <- sim_output_3 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/3)
sim_summary_3

7 Days

#Collect parameters
parms_7 <- parms
parms_7$omega <- 1/7


# Run simulations with the Direct method
set.seed(4)
out_7 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_7,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_7 <- out_7$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_7 <- ggplot(data = plot_data_7, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_7

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_7 <- list()
sim_list_7 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_7 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_7,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_7 <- out_100_7$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_7[[i]] <- sim_data_7
}

sim_output_7 <- bind_rows(sim_list_7)
# Summary table of endpoint data
sim_output_7 <- sim_output_7 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_7

# Make Summary Table of output
sim_summary_7 <- sim_output_7 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/7)
sim_summary_7

10 Days

#Collect parameters
parms_10 <- parms
parms_10$omega <- 1/10


# Run simulations with the Direct method
set.seed(4)
out_10 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_10,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_10 <- out_10$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_10 <- ggplot(data = plot_data_10, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_10

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_10 <- list()
sim_list_10 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_10 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_10,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_10 <- out_100_10$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_10[[i]] <- sim_data_10
}

sim_output_10 <- bind_rows(sim_list_10)
# Summary table of endpoint data
sim_output_10 <- sim_output_10 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_10

# Make Summary Table of output
sim_summary_10 <- sim_output_10 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/10)
sim_summary_10

20 Days

#Collect parameters
parms_20 <- parms
parms_20$omega <- 1/20


# Run simulations with the Direct method
set.seed(4)
out_20 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_20,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_20 <- out_20$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_20 <- ggplot(data = plot_data_20, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_20

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_20 <- list()
sim_list_20 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_20 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_20,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_20 <- out_100_20$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_20[[i]] <- sim_data_20
}

sim_output_20 <- bind_rows(sim_list_20)
# Summary table of endpoint data
sim_output_20 <- sim_output_20 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_20

# Make Summary Table of output
sim_summary_20 <- sim_output_20 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/20)
sim_summary_20

30 Days

#Collect parameters
parms_30 <- parms
parms_30$omega <- 1/30


# Run simulations with the Direct method
set.seed(4)
out_30 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_30,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_30 <- out_30$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_30 <- ggplot(data = plot_data_30, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_30

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_30 <- list()
sim_list_30 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_30 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_30,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_30 <- out_100_30$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_30[[i]] <- sim_data_30
}

sim_output_30 <- bind_rows(sim_list_30)
# Summary table of endpoint data
sim_output_30 <- sim_output_30 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_30

# Make Summary Table of output
sim_summary_30 <- sim_output_30 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/30)
sim_summary_30

40 Days

#Collect parameters
parms_40 <- parms
parms_40$omega <- 1/40


# Run simulations with the Direct method
set.seed(4)
out_40 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_40,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_40 <- out_40$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_40 <- ggplot(data = plot_data_40, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_40

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_40 <- list()
sim_list_40 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_40 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_40,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_40 <- out_100_40$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_40[[i]] <- sim_data_40
}

sim_output_40 <- bind_rows(sim_list_40)
# Summary table of endpoint data
sim_output_40 <- sim_output_40 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_40

# Make Summary Table of output
sim_summary_40 <- sim_output_40 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/40)
sim_summary_40

50 Days

#Collect parameters
parms_50 <- parms
parms_50$omega <- 1/50


# Run simulations with the Direct method
set.seed(4)
out_50 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_50,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_50 <- out_50$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_50 <- ggplot(data = plot_data_50, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_50

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_50 <- list()
sim_list_50 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_50 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_50,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_50 <- out_100_50$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_50[[i]] <- sim_data_50
}

sim_output_50 <- bind_rows(sim_list_50)
# Summary table of endpoint data
sim_output_50 <- sim_output_50 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_50

# Make Summary Table of output
sim_summary_50 <- sim_output_50 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/50)
sim_summary_50

60 Days

#Collect parameters
parms_60 <- parms
parms_60$omega <- 1/60


# Run simulations with the Direct method
set.seed(4)
out_60 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_60,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_60 <- out_60$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_60 <- ggplot(data = plot_data_60, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_60

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_60 <- list()
sim_list_60 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_60 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_60,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_60 <- out_100_60$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_60[[i]] <- sim_data_60
}

sim_output_60 <- bind_rows(sim_list_60)
# Summary table of endpoint data
sim_output_60 <- sim_output_60 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_60

# Make Summary Table of output
sim_summary_60 <- sim_output_60 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/60)
sim_summary_60

70 Days

#Collect parameters
parms_70 <- parms
parms_70$omega <- 1/70


# Run simulations with the Direct method
set.seed(4)
out_70 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_70,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_70 <- out_70$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_70 <- ggplot(data = plot_data_70, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_70

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_70 <- list()
sim_list_70 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_70 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_70,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_70 <- out_100_70$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_70[[i]] <- sim_data_70
}

sim_output_70 <- bind_rows(sim_list_70)
# Summary table of endpoint data
sim_output_70 <- sim_output_70 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_70

# Make Summary Table of output
sim_summary_70 <- sim_output_70 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/70)
sim_summary_70

80 Days

#Collect parameters
parms_80 <- parms
parms_80$omega <- 1/80


# Run simulations with the Direct method
set.seed(4)
out_80 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_80,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_80 <- out_80$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_80 <- ggplot(data = plot_data_80, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_80

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_80 <- list()
sim_list_80 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_80 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_80,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_80 <- out_100_80$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_80[[i]] <- sim_data_80
}

sim_output_80 <- bind_rows(sim_list_80)
# Summary table of endpoint data
sim_output_80 <- sim_output_80 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_80

# Make Summary Table of output
sim_summary_80 <- sim_output_80 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/80)
sim_summary_80

150 Days

#Collect parameters
parms_150 <- parms
parms_150$omega <- 1/150


# Run simulations with the Direct method
set.seed(4)
out_150 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_150,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_150 <- out_150$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_150 <- ggplot(data = plot_data_150, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_150

180 Days

#Collect parameters
parms_180 <- parms
parms_180$omega <- 1/180


# Run simulations with the Direct method
set.seed(4)
out_100 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_180,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_180 <- out_180$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_180 <- ggplot(data = plot_data_180, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_180

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_180 <- list()
sim_list_180 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_180 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_180,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_180 <- out_100_180$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_180[[i]] <- sim_data_180
}

sim_output_180 <- bind_rows(sim_list_180)
# Summary table of endpoint data
sim_output_180 <- sim_output_180 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_180

# Make Summary Table of output
sim_summary_180 <- sim_output_180 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/180)
sim_summary_180

365 Days

#Collect parameters
parms_365 <- parms
parms_365$omega <- 1/365


# Run simulations with the Direct method
set.seed(4)
out_365 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_365,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_365 <- out_365$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_365 <- ggplot(data = plot_data_365, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_365

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_365 <- list()
sim_list_365 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_365 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_365,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_365 <- out_100_365$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_365[[i]] <- sim_data_365
}

sim_output_365 <- bind_rows(sim_list_365)
# Summary table of endpoint data
sim_output_365 <- sim_output_365 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_365

# Make Summary Table of output
sim_summary_365 <- sim_output_365 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/365)
sim_summary_365

Results

waning_results_single <- sim_summary %>%
  bind_rows(sim_summary_1) %>%
  bind_rows(sim_summary_3) %>%
  bind_rows(sim_summary_7) %>%
  bind_rows(sim_summary_10) %>%
  bind_rows(sim_summary_20) %>%
  bind_rows(sim_summary_30) %>%
  bind_rows(sim_summary_40) %>%
  bind_rows(sim_summary_50) %>%
  bind_rows(sim_summary_60) %>%
  bind_rows(sim_summary_70) %>%
  bind_rows(sim_summary_80) %>%
  bind_rows(sim_summary_100) %>%
  bind_rows(sim_summary_150) %>%
  bind_rows(sim_summary_365) %>%
  mutate(immunity_duration = 1/omega) %>%
  arrange(immunity_duration) %>%
  mutate(model="single")

write_csv(waning_results_single, file = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/waning_results_single.csv")

waning_results_single
NA
ggplot(waning_results_single, aes(immunity_duration, sum_persist)) +
  geom_line()+
  geom_point()+
  theme_bw()

Metapopulation Model

###Set-up

# Define Paramenters
patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Patch size
U <- length(patchPopSize)                    # Number of patches
initial_infected <-  as.vector(rmultinom(1, 1, rep(0.5, U)))   # Initial infected (initial infected patch randomly generated)
initial_infected_patch <- which(initial_infected > 0)
simName <- "SIRS metapopulation model"       # Simulation name
tf <- 365*3                                   # Final time

# Agta Hunter-Gatherer contact rates
within_pop_contact = 1
between_pop_contact = 0.5/U     # normalised by number of patches 

#Create the named initial state vector for the U-patch system.

x0_meta <- unlist(lapply(
  seq_len(U), 
  function(i){ 
    c(patchPopSize[i] - initial_infected[i], initial_infected[i], 0, 0, patchPopSize[i])
  }
))

names(x0_meta) <- unlist(lapply(seq_len(U), function(i) paste0(c("S","E","I", "R", "N"), i)))


# Define the state change matrix for a single patch
nu_meta <- matrix(c( -1,  0,  0, +1, +1, -1,  0,  0,  0,  0, # S
                     +1, -1,  0,  0,  0,  0, -1,  0,  0,  0, # E
                      0, +1, -1,  0,  0,  0,  0, -1,  0, -1, # I
                      0,  0, +1, -1,  0,  0,  0,  0, -1,  0, # R 
                      0,  0,  0,  0, +1, -1 ,-1, -1, -1, -1), # N
             nrow=5,byrow=TRUE)

# Define propensity functions
# Mass-action
a_meta <-
  unlist(lapply(
    seq_len(U),
    function(patch) {
      i <- patch
      patches <- 1:U
      #j <- if (patch == 1) U else patch - 1
      other_patches <- patches[-i]
      patch_beta <- c()
      for(k in (1:(U-1))){
        patch_beta[k] = paste0("+(beta_", other_patches[k],i, "*I", other_patches[k], "/N", other_patches[k], ")*S", i)
      }
      c(
        paste0("(beta_", i, i, "*I", i,"/N", i, ")*S",i, paste0(patch_beta, collapse="")), # Infection
        paste0("sigma*E", i),                                       # Becomes infecious
        paste0("gamma*I", i),                                       # Recovery from infection
        paste0("omega*R", i),       # Loss of immunity
        paste0("mu*N", i),                             # Births
        paste0("mu*S", i),                                             # Deaths (S)
        paste0("mu*E", i),                                             # Deaths (E)
        paste0("mu*I", i),                                             # Deaths (I)
        paste0("mu*R", i),                                             # Deaths (R)
        paste0("alpha*I", i)                                           # Deaths from infection
        
      )
    }
  ))

Define functions for calculating R0 from next-generation matrix

# Calculate R0 from NGM

R0ngm <- function(nextgen_matrix) {
  eigenvalues = eigen(nextgen_matrix, only.values = T)
  R0 = max(abs(eigenvalues$values))
  return(R0)
}

beta.ngm <- function(beta_matrix) {
  eigenvalues = eigen(beta_matrix, only.values = T)
  beta_ngm = max(abs(eigenvalues$values))
  return(beta_ngm)
}

Metapopulation Model

#Collect parameters
parms_meta <- list(
  sigma = 0.175,                          # E to I rate
  gamma = 0.2,                           # I to R rate
  omega = 1/100,                         # R to S rate
  mu = demo_sum$Birth_rate_daily_Mean,                            # Birth/death rate per person per day
  alpha = 1/1000) 

# Define transmission terms and populate next-generation matrix
beta <- 0.6

nextgen_matrix <- matrix(nrow = U, ncol = U, data = 0)
beta_matrix <- matrix(nrow = U, ncol = U, data = 0)


for(i in 1:U){
  for(j in 1:U){
    parms_meta[[paste0("beta_",i,i)]] = within_pop_contact*beta
    nextgen_matrix[i,i] = within_pop_contact*beta*(1/parms_meta$gamma)
    parms_meta[[paste0("beta_",j,i)]] = between_pop_contact*beta
    nextgen_matrix[j,i] = between_pop_contact*beta*(1/parms_meta$gamma)
    nextgen_matrix[i,j] = between_pop_contact*beta*(1/parms_meta$gamma)
    parms_meta[[paste0("beta_",j,j)]] = within_pop_contact*beta
    nextgen_matrix[j,j] = within_pop_contact*beta*(1/parms_meta$gamma)
    beta_matrix[i,i] = within_pop_contact*beta
    beta_matrix[j,i] = between_pop_contact*beta
    beta_matrix[i,j] = between_pop_contact*beta
    beta_matrix[j,j] = within_pop_contact*beta
  }
  parms_meta[[paste0("N", i)]] = patchPopSize[i]
}
# Run simulations with the Direct method
set.seed(25)
out_meta <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Plot
plot_data_meta <- out_meta$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta <- ggplot(data = plot_data_meta, aes(x=t, y=count, colour=state))+
  geom_line(alpha=0.8)+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 1, scales = "free_y")+
  labs(x="Time (Days)",
       y="Number of Individuals",
       colour="State")+
  theme_bw()
plot_meta

ggsave(filename = "meta_plot.pdf", 
       plot = plot_meta,
       device = "pdf",
       width = 7, 
       height = 8,
       path = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models")

## Table showing extinction/transmission info for each patch

extinct_data_meta <- out_meta$data %>%
  as_tibble() %>%
  slice_max(t) %>%
  distinct() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N")),
         persist = case_when(state=="I" & count > 0 ~ T, 
                             state=="I" & count == 0 ~ F)) %>%
  drop_na() %>%
  select(patch, count, persist)
extinct_data_meta
beta_meta <- beta.ngm(beta_matrix)
paste0("Beta for whole system = ", beta_meta)
[1] "Beta for whole system = 0.857142857142857"
R0_meta <- R0ngm(nextgen_matrix)
paste0("R0 = ", R0_meta)
[1] "R0 = 4.28571428571429"
paste0("Actual number of infecteds at end of sim = ", sum(extinct_data_meta$count))
[1] "Actual number of infecteds at end of sim = 10"
 # Total number of infecteds at the end of sim across all patches

sim_endpoint_meta <- as_tibble(out_meta$data) %>%
  slice_max(t) %>%
  distinct()


paste0("Did simulation run reach final endpoint?")
[1] "Did simulation run reach final endpoint?"
if (sim_endpoint_meta$t >= tf) {
  print("Yes")
} else {
  print("No")}
[1] "Yes"
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta <- list()
sim_list_meta <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(lapply(
  seq_len(U), 
  function(x){ 
    c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
  }
))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))
  
  out_100_meta <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta <- out_100_meta$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta[[i]] <- sim_data_meta
}

sim_output_meta <- bind_rows(sim_list_meta)
# Summary table of endpoint data
sim_output_meta <- sim_output_meta %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta
# Make Summary Table of output
sim_summary_meta <- sim_output_meta %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/100)
sim_summary_meta

Varying waining immunity

0 Days

#Collect parameters
parms_meta_0 <- parms_meta
parms_meta_0$omega <- 0


# Run simulations with the Direct method
set.seed(4)
out_meta_0 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_0,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_0 <- out_meta_0$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_0 <- ggplot(data = plot_data_meta_0, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_0

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_0 <- list()
sim_list_meta_0 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_0 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_0,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_0 <- out_100_meta_0$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_0[[i]] <- sim_data_meta_0
}

sim_output_meta_0 <- bind_rows(sim_list_meta_0)
# Summary table of endpoint data
sim_output_meta_0 <- sim_output_meta_0 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_0

# Make Summary Table of output
sim_summary_meta_0 <- sim_output_meta_0 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 0)
sim_summary_meta_0

1 Day

#Collect parameters
parms_meta_1 <- parms_meta
parms_meta_1$omega <- 1


# Run simulations with the Direct method
set.seed(4)
out_meta_1 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_1,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_1 <- out_meta_1$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_1 <- ggplot(data = plot_data_meta_1, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_1

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_1 <- list()
sim_list_meta_1 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_1 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_1,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_1 <- out_100_meta_1$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_1[[i]] <- sim_data_meta_1
}

sim_output_meta_1 <- bind_rows(sim_list_meta_1)
# Summary table of endpoint data
sim_output_meta_1 <- sim_output_meta_1 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_1

# Make Summary Table of output
sim_summary_meta_1 <- sim_output_meta_1 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1)
sim_summary_meta_1

3 Days

#Collect parameters
parms_meta_3 <- parms_meta
parms_meta_3$omega <- 1/3


# Run simulations with the Direct method
set.seed(4)
out_meta_3 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_3,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_3 <- out_meta_3$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_3 <- ggplot(data = plot_data_meta_3, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_3

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_3 <- list()
sim_list_meta_3 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_3 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_3,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_3 <- out_100_meta_3$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_3[[i]] <- sim_data_meta_3
}

sim_output_meta_3 <- bind_rows(sim_list_meta_3)
# Summary table of endpoint data
sim_output_meta_3 <- sim_output_meta_3 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_3

# Make Summary Table of output
sim_summary_meta_3 <- sim_output_meta_3 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/3)
sim_summary_meta_3

7 Days

#Collect parameters
parms_meta_7 <- parms_meta
parms_meta_7$omega <- 1/7


# Run simulations with the Direct method
set.seed(4)
out_meta_7 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_7,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_7 <- out_meta_7$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_7 <- ggplot(data = plot_data_meta_7, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_7

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_7 <- list()
sim_list_meta_7 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_7 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_7,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_7 <- out_100_meta_7$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_7[[i]] <- sim_data_meta_7
}

sim_output_meta_7 <- bind_rows(sim_list_meta_7)
# Summary table of endpoint data
sim_output_meta_7 <- sim_output_meta_7 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_7

# Make Summary Table of output
sim_summary_meta_7 <- sim_output_meta_7 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/7)
sim_summary_meta_7

10 Days

#Collect parameters
parms_meta_10 <- parms_meta
parms_meta_10$omega <- 1/10

# Run simulations with the Direct method
set.seed(4)
out_meta_10 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_10,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_10 <- out_meta_10$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_10 <- ggplot(data = plot_data_meta_10, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_10

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_10 <- list()
sim_list_meta_10 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_10 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_10,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_10 <- out_100_meta_10$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_10[[i]] <- sim_data_meta_10
}

sim_output_meta_10 <- bind_rows(sim_list_meta_10)
# Summary table of endpoint data
sim_output_meta_10 <- sim_output_meta_10 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))

# Make Summary Table of output
sim_summary_meta_10 <- sim_output_meta_10 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/14)
sim_summary_meta_10

20 Days

#Collect parameters
parms_meta_20 <- parms_meta
parms_meta_20$omega <- 1/20


# Run simulations with the Direct method
set.seed(4)
out_meta_20 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_20,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_20 <- out_meta_20$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_20 <- ggplot(data = plot_data_meta_20, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_20

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_20 <- list()
sim_list_meta_20 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_20 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_20,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_20 <- out_100_meta_20$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_20[[i]] <- sim_data_meta_20
}

sim_output_meta_20 <- bind_rows(sim_list_meta_20)
# Summary table of endpoint data
sim_output_meta_20 <- sim_output_meta_20 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_20

# Make Summary Table of output
sim_summary_meta_20 <- sim_output_meta_20 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/20)
sim_summary_meta_20

30 Days

#Collect parameters
parms_meta_30 <- parms_meta
parms_meta_30$omega <- 1/30


# Run simulations with the Direct method
set.seed(4)
out_meta_30 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_30,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_30 <- out_meta_30$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_30 <- ggplot(data = plot_data_meta_30, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_30

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_30 <- list()
sim_list_meta_30 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_30 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_30,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_30 <- out_100_meta_30$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_30[[i]] <- sim_data_meta_30
}

sim_output_meta_30 <- bind_rows(sim_list_meta_30)
# Summary table of endpoint data
sim_output_meta_30 <- sim_output_meta_30 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_30

# Make Summary Table of output
sim_summary_meta_30 <- sim_output_meta_30 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/30)
sim_summary_meta_30

40 Days

#Collect parameters
parms_meta_40 <- parms_meta
parms_meta_40$omega <- 1/40


# Run simulations with the Direct method
set.seed(4)
out_meta_40 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_40,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_40 <- out_meta_40$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_40 <- ggplot(data = plot_data_meta_40, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_40

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_40 <- list()
sim_list_meta_40 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_40 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_40,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_40 <- out_100_meta_40$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_40[[i]] <- sim_data_meta_40
}

sim_output_meta_40 <- bind_rows(sim_list_meta_40)
# Summary table of endpoint data
sim_output_meta_40 <- sim_output_meta_40 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_40

# Make Summary Table of output
sim_summary_meta_40 <- sim_output_meta_40 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/40)
sim_summary_meta_40

50 Days

#Collect parameters
parms_meta_50 <- parms_meta
parms_meta_50$omega <- 1/50


# Run simulations with the Direct method
set.seed(4)
out_meta_50 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_50,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_50 <- out_meta_50$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_50 <- ggplot(data = plot_data_meta_50, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_50

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_50 <- list()
sim_list_meta_50 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_50 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_50,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_50 <- out_100_meta_50$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_50[[i]] <- sim_data_meta_50
}

sim_output_meta_50 <- bind_rows(sim_list_meta_50)
# Summary table of endpoint data
sim_output_meta_50 <- sim_output_meta_50 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_50

# Make Summary Table of output
sim_summary_meta_50 <- sim_output_meta_50 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/50)
sim_summary_meta_50

60 Days

#Collect parameters
parms_meta_60 <- parms_meta
parms_meta_60$omega <- 1/60


# Run simulations with the Direct method
set.seed(4)
out_meta_60 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_60,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_60 <- out_meta_60$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_60 <- ggplot(data = plot_data_meta_60, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_60

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_60 <- list()
sim_list_meta_60 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_60 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_60,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_60 <- out_100_meta_60$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_60[[i]] <- sim_data_meta_60
}

sim_output_meta_60 <- bind_rows(sim_list_meta_60)
# Summary table of endpoint data
sim_output_meta_60 <- sim_output_meta_60 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_60

# Make Summary Table of output
sim_summary_meta_60 <- sim_output_meta_60 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/60)
sim_summary_meta_60

70 Days

#Collect parameters
parms_meta_70 <- parms_meta
parms_meta_70$omega <- 1/70


# Run simulations with the Direct method
set.seed(4)
out_meta_70 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_70,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_70 <- out_meta_70$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_70 <- ggplot(data = plot_data_meta_70, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_70

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_70 <- list()
sim_list_meta_70 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_70 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_70,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_70 <- out_100_meta_70$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_70[[i]] <- sim_data_meta_70
}

sim_output_meta_70 <- bind_rows(sim_list_meta_70)
# Summary table of endpoint data
sim_output_meta_70 <- sim_output_meta_70 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_70

# Make Summary Table of output
sim_summary_meta_70 <- sim_output_meta_70 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/70)
sim_summary_meta_70

80 Days

#Collect parameters
parms_meta_80 <- parms_meta
parms_meta_80$omega <- 1/80


# Run simulations with the Direct method
set.seed(4)
out_meta_80 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_80,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_80 <- out_meta_80$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_80 <- ggplot(data = plot_data_meta_80, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_80

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_80 <- list()
sim_list_meta_80 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_80 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_80,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_80 <- out_100_meta_80$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_80[[i]] <- sim_data_meta_80
}

sim_output_meta_80 <- bind_rows(sim_list_meta_80)
# Summary table of endpoint data
sim_output_meta_80 <- sim_output_meta_80 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_80

# Make Summary Table of output
sim_summary_meta_80 <- sim_output_meta_80 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/80)
sim_summary_meta_80

90 Days

#Collect parameters
parms_meta_90 <- parms_meta
parms_meta_90$omega <- 1/90


# Run simulations with the Direct method
set.seed(4)
out_meta_90 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_90,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_90 <- out_meta_90$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_90 <- ggplot(data = plot_data_meta_90, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_90

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_90 <- list()
sim_list_meta_90 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_90 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_90,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_90 <- out_100_meta_90$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_90[[i]] <- sim_data_meta_90
}

sim_output_meta_90 <- bind_rows(sim_list_meta_90)
# Summary table of endpoint data
sim_output_meta_90 <- sim_output_meta_90 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_90

# Make Summary Table of output
sim_summary_meta_90 <- sim_output_meta_90 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/90)
sim_summary_meta_90

180 Days

#Collect parameters
parms_meta_100 <- parms_meta
parms_meta_100$omega <- 1/100


# Run simulations with the Direct method
set.seed(20)
out_meta_100 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_100,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_100 <- out_meta_100$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_100 <- ggplot(data = plot_data_meta_100, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_100

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_100 <- list()
sim_list_meta_100 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_100 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_100,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_100 <- out_100_meta_100$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_100[[i]] <- sim_data_meta_100
}

sim_output_meta_100 <- bind_rows(sim_list_meta_100)
# Summary table of endpoint data
sim_output_meta_100 <- sim_output_meta_100 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_100

# Make Summary Table of output
sim_summary_meta_100 <- sim_output_meta_100 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/100)
sim_summary_meta_100

110 Days

#Collect parameters
parms_meta_110 <- parms_meta
parms_meta_110$omega <- 1/110


# Run simulations with the Direct method
set.seed(4)
out_meta_110 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_110,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_110 <- out_meta_110$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_110 <- ggplot(data = plot_data_meta_110, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_110

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_110 <- list()
sim_list_meta_110 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_110 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_110,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_110 <- out_100_meta_110$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_110[[i]] <- sim_data_meta_110
}

sim_output_meta_110 <- bind_rows(sim_list_meta_110)
# Summary table of endpoint data
sim_output_meta_110 <- sim_output_meta_110 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_110

# Make Summary Table of output
sim_summary_meta_110 <- sim_output_meta_110 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/110)
sim_summary_meta_110

120 Days

#Collect parameters
parms_meta_120 <- parms_meta
parms_meta_120$omega <- 1/120


# Run simulations with the Direct method
set.seed(4)
out_meta_120 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_120,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_120 <- out_meta_120$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_120 <- ggplot(data = plot_data_meta_120, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_120

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_120 <- list()
sim_list_meta_120 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_120 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_120,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_120 <- out_100_meta_120$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_120[[i]] <- sim_data_meta_120
}

sim_output_meta_120 <- bind_rows(sim_list_meta_120)
# Summary table of endpoint data
sim_output_meta_120 <- sim_output_meta_120 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_120

# Make Summary Table of output
sim_summary_meta_120 <- sim_output_meta_120 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/120)
sim_summary_meta_120

130 Days

#Collect parameters
parms_meta_130 <- parms_meta
parms_meta_130$omega <- 1/130


# Run simulations with the Direct method
set.seed(4)
out_meta_130 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_130,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_130 <- out_meta_130$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_130 <- ggplot(data = plot_data_meta_130, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_130

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_130 <- list()
sim_list_meta_130 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_130 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_130,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_130 <- out_100_meta_130$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_130[[i]] <- sim_data_meta_130
}

sim_output_meta_130 <- bind_rows(sim_list_meta_130)
# Summary table of endpoint data
sim_output_meta_130 <- sim_output_meta_130 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_130

# Make Summary Table of output
sim_summary_meta_130 <- sim_output_meta_130 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/130)
sim_summary_meta_130

150 Days

#Collect parameters
parms_meta_150 <- parms_meta
parms_meta_150$omega <- 1/150


# Run simulations with the Direct method
set.seed(4)
out_meta_150 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_150,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_150 <- out_meta_150$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_150 <- ggplot(data = plot_data_meta_150, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_150

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_150 <- list()
sim_list_meta_150 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_150 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_150,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_150 <- out_100_meta_150$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_150[[i]] <- sim_data_meta_150
}

sim_output_meta_150 <- bind_rows(sim_list_meta_150)
# Summary table of endpoint data
sim_output_meta_150 <- sim_output_meta_150 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_150

# Make Summary Table of output
sim_summary_meta_150 <- sim_output_meta_150 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/150)
sim_summary_meta_150

220 Days

#Collect parameters
parms_meta_220 <- parms_meta
parms_meta_220$omega <- 1/220


# Run simulations with the Direct method
set.seed(4)
out_meta_220 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_220,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_220 <- out_meta_220$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_220 <- ggplot(data = plot_data_meta_220, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_220

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_220 <- list()
sim_list_meta_220 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_220 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_220,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_220 <- out_100_meta_220$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_220[[i]] <- sim_data_meta_220
}

sim_output_meta_220 <- bind_rows(sim_list_meta_220)
# Summary table of endpoint data
sim_output_meta_220 <- sim_output_meta_220 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_220

# Make Summary Table of output
sim_summary_meta_220 <- sim_output_meta_220 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/220)
sim_summary_meta_220

270 Days

#Collect parameters
parms_meta_270 <- parms_meta
parms_meta_270$omega <- 1/270


# Run simulations with the Direct method
set.seed(4)
out_meta_270 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_270,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_270 <- out_meta_270$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_270 <- ggplot(data = plot_data_meta_270, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_270

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_270 <- list()
sim_list_meta_270 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_270 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_270,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_270 <- out_100_meta_270$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_270[[i]] <- sim_data_meta_270
}

sim_output_meta_270 <- bind_rows(sim_list_meta_270)
# Summary table of endpoint data
sim_output_meta_270 <- sim_output_meta_270 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_270

# Make Summary Table of output
sim_summary_meta_270 <- sim_output_meta_270 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/270)
sim_summary_meta_270

365 Days

#Collect parameters
parms_meta_365 <- parms_meta
parms_meta_365$omega <- 1/365


# Run simulations with the Direct method
set.seed(4)
out_meta_365 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_365,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_365 <- out_meta_365$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_365 <- ggplot(data = plot_data_meta_365, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_365

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_365 <- list()
sim_list_meta_365 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_365 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_365,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_365 <- out_100_meta_365$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_365[[i]] <- sim_data_meta_365
}

sim_output_meta_365 <- bind_rows(sim_list_meta_365)
# Summary table of endpoint data
sim_output_meta_365 <- sim_output_meta_365 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_365

# Make Summary Table of output
sim_summary_meta_365 <- sim_output_meta_365 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/365)
sim_summary_meta_365

Single

Results

waning_results <- sim_summary_meta %>%
  bind_rows(sim_summary_meta_3) %>%
  bind_rows(sim_summary_meta_7) %>%
  bind_rows(sim_summary_meta_10) %>%
  bind_rows(sim_summary_meta_20) %>%
  bind_rows(sim_summary_meta_30) %>%
  bind_rows(sim_summary_meta_40) %>%
  bind_rows(sim_summary_meta_50) %>%
  bind_rows(sim_summary_meta_60) %>%
  bind_rows(sim_summary_meta_70) %>%
  bind_rows(sim_summary_meta_80) %>%
  bind_rows(sim_summary_meta_90) %>%
  bind_rows(sim_summary_meta_100) %>%
  bind_rows(sim_summary_meta_110) %>%
  bind_rows(sim_summary_meta_120) %>%
  bind_rows(sim_summary_meta_130) %>%
  bind_rows(sim_summary_meta_150) %>%
  bind_rows(sim_summary_meta_220) %>%
  bind_rows(sim_summary_meta_270) %>%
  bind_rows(sim_summary_meta_365) %>%
  mutate(immunity_duration = 1/omega) %>%
  arrange(immunity_duration) %>%
  mutate(model = "meta")

write_csv(waning_results, file = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/waning_results.csv")

waning_results
NA
ggplot(waning_results, aes(immunity_duration, sum_persist)) +
  geom_line()+
  geom_point()+
  theme_bw()

3 Metapopulation Model

###Set-up

# Define Paramenters
patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Patch size
U <- length(patchPopSize_3)                    # Number of patches
initial_infected <-  as.vector(rmultinom(1, 1, rep(0.5, U)))   # Initial infected (initial infected patch randomly generated)
initial_infected_patch <- which(initial_infected > 0)
simName <- "SIRS metapopulation model"       # Simulation name
tf <- 365*3                                   # Final time

# Agta Hunter-Gatherer contact rates
within_pop_contact = 1
between_pop_contact = 0.5/U     # normalised by number of patches 

#Create the named initial state vector for the U-patch system.

x0_3_meta <- unlist(lapply(
  seq_len(U), 
  function(i){ 
    c(patchPopSize_3[i] - initial_infected[i], initial_infected[i], 0, 0, patchPopSize_3[i])
  }
))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(i) paste0(c("S","E","I", "R", "N"), i)))


# Define the state change matrix for a single patch
nu_3_meta <- matrix(c( -1,  0,  0, +1, +1, -1,  0,  0,  0,  0, # S
                     +1, -1,  0,  0,  0,  0, -1,  0,  0,  0, # E
                      0, +1, -1,  0,  0,  0,  0, -1,  0, -1, # I
                      0,  0, +1, -1,  0,  0,  0,  0, -1,  0, # R 
                      0,  0,  0,  0, +1, -1 ,-1, -1, -1, -1), # N
             nrow=5,byrow=TRUE)

# Define propensity functions
# Mass-action
a_3_meta <-
  unlist(lapply(
    seq_len(U),
    function(patch) {
      i <- patch
      patches <- 1:U
      #j <- if (patch == 1) U else patch - 1
      other_patches <- patches[-i]
      patch_beta <- c()
      for(k in (1:(U-1))){
        patch_beta[k] = paste0("+(beta_", other_patches[k],i, "*I", other_patches[k], "/N", other_patches[k], ")*S", i)
      }
      c(
        paste0("(beta_", i, i, "*I", i,"/N", i, ")*S",i, paste0(patch_beta, collapse="")), # Infection
        paste0("sigma*E", i),                                       # Becomes infecious
        paste0("gamma*I", i),                                       # Recovery from infection
        paste0("omega*R", i),       # Loss of immunity
        paste0("mu*N", i),                             # Births
        paste0("mu*S", i),                                             # Deaths (S)
        paste0("mu*E", i),                                             # Deaths (E)
        paste0("mu*I", i),                                             # Deaths (I)
        paste0("mu*R", i),                                             # Deaths (R)
        paste0("alpha*I", i)                                           # Deaths from infection
        
      )
    }
  ))

Metapopulation Model

#Collect parameters
parms_3_meta <- list(
  sigma = 0.175,                          # E to I rate
  gamma = 0.2,                           # I to R rate
  omega = 1/100,                         # R to S rate
  mu = demo_sum$Birth_rate_daily_Mean,                            # Birth/death rate per person per day
  alpha = 1/1000) 

# Define transmission terms and populate next-generation matrix
beta <- 0.6

nextgen_3_matrix <- matrix(nrow = U, ncol = U, data = 0)
beta_3_matrix <- matrix(nrow = U, ncol = U, data = 0)


for(i in 1:U){
  for(j in 1:U){
    parms_3_meta[[paste0("beta_",i,i)]] = within_pop_contact*beta
    nextgen_3_matrix[i,i] = within_pop_contact*beta*(1/parms_3_meta$gamma)
    parms_3_meta[[paste0("beta_",j,i)]] = between_pop_contact*beta
    nextgen_3_matrix[j,i] = between_pop_contact*beta*(1/parms_3_meta$gamma)
    nextgen_3_matrix[i,j] = between_pop_contact*beta*(1/parms_3_meta$gamma)
    parms_3_meta[[paste0("beta_",j,j)]] = within_pop_contact*beta
    nextgen_3_matrix[j,j] = within_pop_contact*beta*(1/parms_3_meta$gamma)
    beta_3_matrix[i,i] = within_pop_contact*beta
    beta_3_matrix[j,i] = between_pop_contact*beta
    beta_3_matrix[i,j] = between_pop_contact*beta
    beta_3_matrix[j,j] = within_pop_contact*beta
  }
  parms_3_meta[[paste0("N", i)]] = patchPopSize_3[i]
}
# Run simulations with the Direct method
set.seed(25)
out_3_meta <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Plot
plot_data_3_meta <- out_3_meta$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta <- ggplot(data = plot_data_3_meta, aes(x=t, y=count, colour=state))+
  geom_line(alpha=0.8)+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 1, scales = "free_y")+
  labs(x="Time (Days)",
       y="Number of Individuals",
       colour="State")+
  theme_bw()
plot_3_meta

ggsave(filename = "meta_plot.pdf", 
       plot = plot_3_meta,
       device = "pdf",
       width = 7, 
       height = 8,
       path = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models")

## Table showing extinction/transmission info for each patch

extinct_data_3_meta <- out_3_meta$data %>%
  as_tibble() %>%
  slice_max(t) %>%
  distinct() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N")),
         persist = case_when(state=="I" & count > 0 ~ T, 
                             state=="I" & count == 0 ~ F)) %>%
  drop_na() %>%
  select(patch, count, persist)
extinct_data_3_meta
beta_3_meta <- beta.ngm(beta_3_matrix)
paste0("Beta for whole system = ", beta_3_meta)
[1] "Beta for whole system = 0.8"
R0_3_meta <- R0ngm(nextgen_3_matrix)
paste0("R0 = ", R0_3_meta)
[1] "R0 = 4"
paste0("Actual number of infecteds at end of sim = ", sum(extinct_data_3_meta$count))
[1] "Actual number of infecteds at end of sim = 0"
 # Total number of infecteds at the end of sim across all patches

sim_endpoint_3_meta <- as_tibble(out_3_meta$data) %>%
  slice_max(t) %>%
  distinct()


paste0("Did simulation run reach final endpoint?")
[1] "Did simulation run reach final endpoint?"
if (sim_endpoint_3_meta$t >= tf) {
  print("Yes")
} else {
  print("No")}
[1] "Yes"
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta <- list()
sim_list_3_meta <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(lapply(
  seq_len(U), 
  function(x){ 
    c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
  }
))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))
  
  out_100_3_meta <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta <- out_100_3_meta$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta[[i]] <- sim_data_3_meta
}

sim_output_3_meta <- bind_rows(sim_list_3_meta)
# Summary table of endpoint data
sim_output_3_meta <- sim_output_3_meta %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta
# Make Summary Table of output
sim_summary_3_meta <- sim_output_3_meta %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/100)
sim_summary_3_meta

Varying waining immunity

0 Days

#Collect parameters
parms_3_meta_0 <- parms_3_meta
parms_3_meta_0$omega <- 0


# Run simulations with the Direct method
set.seed(4)
out_3_meta_0 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_0,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_0 <- out_3_meta_0$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_0 <- ggplot(data = plot_data_3_meta_0, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_0

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_0 <- list()
sim_list_3_meta_0 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_0 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_0,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_0 <- out_100_3_meta_0$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_0[[i]] <- sim_data_3_meta_0
}

sim_output_3_meta_0 <- bind_rows(sim_list_3_meta_0)
# Summary table of endpoint data
sim_output_3_meta_0 <- sim_output_3_meta_0 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_0

# Make Summary Table of output
sim_summary_3_meta_0 <- sim_output_3_meta_0 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 0)
sim_summary_3_meta_0

1 Day

#Collect parameters
parms_3_meta_1 <- parms_3_meta
parms_3_meta_1$omega <- 1


# Run simulations with the Direct method
set.seed(4)
out_3_meta_1 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_1,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_1 <- out_3_meta_1$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_1 <- ggplot(data = plot_data_3_meta_1, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_1

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_1 <- list()
sim_list_3_meta_1 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_1 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_1,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_1 <- out_100_3_meta_1$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_1[[i]] <- sim_data_3_meta_1
}

sim_output_3_meta_1 <- bind_rows(sim_list_3_meta_1)
# Summary table of endpoint data
sim_output_3_meta_1 <- sim_output_3_meta_1 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_1

# Make Summary Table of output
sim_summary_3_meta_1 <- sim_output_3_meta_1 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1)
sim_summary_3_meta_1

3 Days

#Collect parameters
parms_3_meta_3 <- parms_3_meta
parms_3_meta_3$omega <- 1/3


# Run simulations with the Direct method
set.seed(4)
out_3_meta_3 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_3,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_3 <- out_3_meta_3$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_3 <- ggplot(data = plot_data_3_meta_3, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_3

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_3 <- list()
sim_list_3_meta_3 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_3 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_3,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_3 <- out_100_3_meta_3$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_3[[i]] <- sim_data_3_meta_3
}

sim_output_3_meta_3 <- bind_rows(sim_list_3_meta_3)
# Summary table of endpoint data
sim_output_3_meta_3 <- sim_output_3_meta_3 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_3

# Make Summary Table of output
sim_summary_3_meta_3 <- sim_output_3_meta_3 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/3)
sim_summary_3_meta_3

7 Days

#Collect parameters
parms_3_meta_7 <- parms_3_meta
parms_3_meta_7$omega <- 1/7


# Run simulations with the Direct method
set.seed(4)
out_3_meta_7 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_7,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_7 <- out_3_meta_7$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_7 <- ggplot(data = plot_data_3_meta_7, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_7

x0_3_meta
S1 E1 I1 R1 N1 S2 E2 I2 R2 N2 S3 E3 I3 R3 N3 
96  0  0  0 96 40  1  0  0 41 47  0  0  0 47 
# Summary table of endpoint data
sim_output_3_meta_7 <- sim_output_3_meta_7 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_7

# Make Summary Table of output
sim_summary_3_meta_7 <- sim_output_3_meta_7 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/7)
sim_summary_3_meta_7

10 Days

#Collect parameters
parms_3_meta_10 <- parms_3_meta
parms_3_meta_10$omega <- 1/10

# Run simulations with the Direct method
set.seed(4)
out_3_meta_10 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_10,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_10 <- out_3_meta_10$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_10 <- ggplot(data = plot_data_3_meta_10, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_10

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_10 <- list()
sim_list_3_meta_10 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_10 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_10,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_10 <- out_100_3_meta_10$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_10[[i]] <- sim_data_3_meta_10
}

sim_output_3_meta_10 <- bind_rows(sim_list_3_meta_10)
# Summary table of endpoint data
sim_output_3_meta_10 <- sim_output_3_meta_10 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))

# Make Summary Table of output
sim_summary_3_meta_10 <- sim_output_3_meta_10 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/14)
sim_summary_3_meta_10

20 Days

#Collect parameters
parms_3_meta_20 <- parms_3_meta
parms_3_meta_20$omega <- 1/20


# Run simulations with the Direct method
set.seed(4)
out_3_meta_20 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_20,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_20 <- out_3_meta_20$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_20 <- ggplot(data = plot_data_3_meta_20, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_20

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_20 <- list()
sim_list_3_meta_20 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_20 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_20,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_20 <- out_100_3_meta_20$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_20[[i]] <- sim_data_3_meta_20
}

sim_output_3_meta_20 <- bind_rows(sim_list_3_meta_20)
# Summary table of endpoint data
sim_output_3_meta_20 <- sim_output_3_meta_20 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_20

# Make Summary Table of output
sim_summary_3_meta_20 <- sim_output_3_meta_20 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/20)
sim_summary_3_meta_20

30 Days

#Collect parameters
parms_3_meta_30 <- parms_3_meta
parms_3_meta_30$omega <- 1/30


# Run simulations with the Direct method
set.seed(4)
out_3_meta_30 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_30,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_30 <- out_3_meta_30$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_30 <- ggplot(data = plot_data_3_meta_30, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_30

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_30 <- list()
sim_list_3_meta_30 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_30 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_30,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_30 <- out_100_3_meta_30$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_30[[i]] <- sim_data_3_meta_30
}

sim_output_3_meta_30 <- bind_rows(sim_list_3_meta_30)
# Summary table of endpoint data
sim_output_3_meta_30 <- sim_output_3_meta_30 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_30

# Make Summary Table of output
sim_summary_3_meta_30 <- sim_output_3_meta_30 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/30)
sim_summary_3_meta_30

40 Days

#Collect parameters
parms_3_meta_40 <- parms_3_meta
parms_3_meta_40$omega <- 1/40


# Run simulations with the Direct method
set.seed(4)
out_3_meta_40 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_40,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_40 <- out_3_meta_40$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_40 <- ggplot(data = plot_data_3_meta_40, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_40

# Summary table of endpoint data
sim_output_3_meta_40 <- sim_output_3_meta_40 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_40

# Make Summary Table of output
sim_summary_3_meta_40 <- sim_output_3_meta_40 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/40)
sim_summary_3_meta_40

50 Days

#Collect parameters
parms_3_meta_50 <- parms_3_meta
parms_3_meta_50$omega <- 1/50


# Run simulations with the Direct method
set.seed(4)
out_3_meta_50 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_50,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_50 <- out_3_meta_50$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_50 <- ggplot(data = plot_data_3_meta_50, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_50

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_50 <- list()
sim_list_3_meta_50 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_50 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_50,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_50 <- out_100_3_meta_50$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_50[[i]] <- sim_data_3_meta_50
}

sim_output_3_meta_50 <- bind_rows(sim_list_3_meta_50)
# Summary table of endpoint data
sim_output_3_meta_50 <- sim_output_3_meta_50 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_50

# Make Summary Table of output
sim_summary_3_meta_50 <- sim_output_3_meta_50 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/50)
sim_summary_3_meta_50

60 Days

#Collect parameters
parms_3_meta_60 <- parms_3_meta
parms_3_meta_60$omega <- 1/60


# Run simulations with the Direct method
set.seed(4)
out_3_meta_60 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_60,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_60 <- out_3_meta_60$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_60 <- ggplot(data = plot_data_3_meta_60, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_60

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_60 <- list()
sim_list_3_meta_60 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_60 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_60,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_60 <- out_100_3_meta_60$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_60[[i]] <- sim_data_3_meta_60
}

sim_output_3_meta_60 <- bind_rows(sim_list_3_meta_60)
# Summary table of endpoint data
sim_output_3_meta_60 <- sim_output_3_meta_60 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_60

# Make Summary Table of output
sim_summary_3_meta_60 <- sim_output_3_meta_60 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/60)
sim_summary_3_meta_60

70 Days

#Collect parameters
parms_3_meta_70 <- parms_3_meta
parms_3_meta_70$omega <- 1/70


# Run simulations with the Direct method
set.seed(4)
out_3_meta_70 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_70,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_70 <- out_3_meta_70$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_70 <- ggplot(data = plot_data_3_meta_70, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_70

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_70 <- list()
sim_list_3_meta_70 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_70 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_70,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_70 <- out_100_3_meta_70$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_70[[i]] <- sim_data_3_meta_70
}

sim_output_3_meta_70 <- bind_rows(sim_list_3_meta_70)
# Summary table of endpoint data
sim_output_3_meta_70 <- sim_output_3_meta_70 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_70

# Make Summary Table of output
sim_summary_3_meta_70 <- sim_output_3_meta_70 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/70)
sim_summary_3_meta_70

80 Days

#Collect parameters
parms_3_meta_80 <- parms_3_meta
parms_3_meta_80$omega <- 1/80


# Run simulations with the Direct method
set.seed(4)
out_3_meta_80 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_80,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_80 <- out_3_meta_80$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_80 <- ggplot(data = plot_data_3_meta_80, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_80

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_80 <- list()
sim_list_3_meta_80 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_80 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_80,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_80 <- out_100_3_meta_80$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_80[[i]] <- sim_data_3_meta_80
}

sim_output_3_meta_80 <- bind_rows(sim_list_3_meta_80)
# Summary table of endpoint data
sim_output_3_meta_80 <- sim_output_3_meta_80 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_80

# Make Summary Table of output
sim_summary_3_meta_80 <- sim_output_3_meta_80 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/80)
sim_summary_3_meta_80

90 Days

#Collect parameters
parms_3_meta_90 <- parms_3_meta
parms_3_meta_90$omega <- 1/90


# Run simulations with the Direct method
set.seed(4)
out_3_meta_90 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_90,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_90 <- out_3_meta_90$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_90 <- ggplot(data = plot_data_3_meta_90, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_90

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_90 <- list()
sim_list_3_meta_90 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_90 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_90,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_90 <- out_100_3_meta_90$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_90[[i]] <- sim_data_3_meta_90
}

sim_output_3_meta_90 <- bind_rows(sim_list_3_meta_90)
# Summary table of endpoint data
sim_output_3_meta_90 <- sim_output_3_meta_90 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_90

# Make Summary Table of output
sim_summary_3_meta_90 <- sim_output_3_meta_90 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/90)
sim_summary_3_meta_90

180 Days

#Collect parameters
parms_3_meta_180 <- parms_3_meta
parms_3_meta_180$omega <- 1/180


# Run simulations with the Direct method
set.seed(20)
out_3_meta_180 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_180,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_180 <- out_3_meta_180$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_180 <- ggplot(data = plot_data_3_meta_180, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_180

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_180 <- list()
sim_list_3_meta_180 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_180 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_180,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_180 <- out_100_3_meta_180$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_180[[i]] <- sim_data_3_meta_180
}

sim_output_3_meta_180 <- bind_rows(sim_list_3_meta_180)
# Summary table of endpoint data
sim_output_3_meta_180 <- sim_output_3_meta_180 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_180

# Make Summary Table of output
sim_summary_3_meta_180 <- sim_output_3_meta_180 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/180)
sim_summary_3_meta_180

110 Days

#Collect parameters
parms_3_meta_110 <- parms_3_meta
parms_3_meta_110$omega <- 1/110


# Run simulations with the Direct method
set.seed(4)
out_3_meta_110 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_110,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_110 <- out_3_meta_110$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_110 <- ggplot(data = plot_data_3_meta_110, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_110

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_110 <- list()
sim_list_3_meta_110 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_110 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_110,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_110 <- out_100_3_meta_110$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_110[[i]] <- sim_data_3_meta_110
}

sim_output_3_meta_110 <- bind_rows(sim_list_3_meta_110)
# Summary table of endpoint data
sim_output_3_meta_110 <- sim_output_3_meta_110 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_110

# Make Summary Table of output
sim_summary_3_meta_110 <- sim_output_3_meta_110 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/110)
sim_summary_3_meta_110

120 Days

#Collect parameters
parms_3_meta_120 <- parms_3_meta
parms_3_meta_120$omega <- 1/120


# Run simulations with the Direct method
set.seed(4)
out_3_meta_120 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_120,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_120 <- out_3_meta_120$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_120 <- ggplot(data = plot_data_3_meta_120, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_120

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_120 <- list()
sim_list_3_meta_120 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_120 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_120,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_120 <- out_100_3_meta_120$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_120[[i]] <- sim_data_3_meta_120
}

sim_output_3_meta_120 <- bind_rows(sim_list_3_meta_120)
# Summary table of endpoint data
sim_output_3_meta_120 <- sim_output_3_meta_120 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_120

# Make Summary Table of output
sim_summary_3_meta_120 <- sim_output_3_meta_120 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/120)
sim_summary_3_meta_120

130 Days

#Collect parameters
parms_3_meta_130 <- parms_3_meta
parms_3_meta_130$omega <- 1/130


# Run simulations with the Direct method
set.seed(4)
out_3_meta_130 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_130,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_130 <- out_3_meta_130$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_130 <- ggplot(data = plot_data_3_meta_130, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_130

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_130 <- list()
sim_list_3_meta_130 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_130 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_130,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_130 <- out_100_3_meta_130$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_130[[i]] <- sim_data_3_meta_130
}

sim_output_3_meta_130 <- bind_rows(sim_list_3_meta_130)
# Summary table of endpoint data
sim_output_3_meta_130 <- sim_output_3_meta_130 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_130

# Make Summary Table of output
sim_summary_3_meta_130 <- sim_output_3_meta_130 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/130)
sim_summary_3_meta_130

150 Days

#Collect parameters
parms_3_meta_150 <- parms_3_meta
parms_3_meta_150$omega <- 1/150


# Run simulations with the Direct method
set.seed(4)
out_3_meta_150 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_150,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_150 <- out_3_meta_150$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_150 <- ggplot(data = plot_data_3_meta_150, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_150

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_150 <- list()
sim_list_3_meta_150 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_150 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_150,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_150 <- out_100_3_meta_150$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_150[[i]] <- sim_data_3_meta_150
}

sim_output_3_meta_150 <- bind_rows(sim_list_3_meta_150)
# Summary table of endpoint data
sim_output_3_meta_150 <- sim_output_3_meta_150 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_150

# Make Summary Table of output
sim_summary_3_meta_150 <- sim_output_3_meta_150 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/150)
sim_summary_3_meta_150

220 Days

#Collect parameters
parms_3_meta_220 <- parms_3_meta
parms_3_meta_220$omega <- 1/220


# Run simulations with the Direct method
set.seed(4)
out_3_meta_220 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_220,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_220 <- out_3_meta_220$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_220 <- ggplot(data = plot_data_3_meta_220, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_220

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_220 <- list()
sim_list_3_meta_220 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_220 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_220,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_220 <- out_100_3_meta_220$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_220[[i]] <- sim_data_3_meta_220
}

sim_output_3_meta_220 <- bind_rows(sim_list_3_meta_220)
# Summary table of endpoint data
sim_output_3_meta_220 <- sim_output_3_meta_220 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_220

# Make Summary Table of output
sim_summary_3_meta_220 <- sim_output_3_meta_220 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/220)
sim_summary_3_meta_220

270 Days

#Collect parameters
parms_3_meta_270 <- parms_3_meta
parms_3_meta_270$omega <- 1/270


# Run simulations with the Direct method
set.seed(4)
out_3_meta_270 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_270,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_270 <- out_3_meta_270$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_270 <- ggplot(data = plot_data_3_meta_270, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_270

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_270 <- list()
sim_list_3_meta_270 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_270 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_270,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_270 <- out_100_3_meta_270$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_270[[i]] <- sim_data_3_meta_270
}

sim_output_3_meta_270 <- bind_rows(sim_list_3_meta_270)
# Summary table of endpoint data
sim_output_3_meta_270 <- sim_output_3_meta_270 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_270

# Make Summary Table of output
sim_summary_3_meta_270 <- sim_output_3_meta_270 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/270)
sim_summary_3_meta_270

365 Days

#Collect parameters
parms_3_meta_365 <- parms_3_meta
parms_3_meta_365$omega <- 1/365


# Run simulations with the Direct method
set.seed(4)
out_3_meta_365 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_365,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_365 <- out_3_meta_365$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_365 <- ggplot(data = plot_data_3_meta_365, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_365

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_365 <- list()
sim_list_3_meta_365 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_365 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_365,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_365 <- out_100_3_meta_365$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_365[[i]] <- sim_data_3_meta_365
}

sim_output_3_meta_365 <- bind_rows(sim_list_3_meta_365)
# Summary table of endpoint data
sim_output_3_meta_365 <- sim_output_3_meta_365 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_365

# Make Summary Table of output
sim_summary_3_meta_365 <- sim_output_3_meta_365 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/365)
sim_summary_3_meta_365

Single

Results

waning_results_3 <- sim_summary_3_meta %>%
  bind_rows(sim_summary_3_meta_3) %>%
  bind_rows(sim_summary_3_meta_7) %>%
  bind_rows(sim_summary_3_meta_10) %>%
  bind_rows(sim_summary_3_meta_20) %>%
  bind_rows(sim_summary_3_meta_30) %>%
  bind_rows(sim_summary_3_meta_40) %>%
  bind_rows(sim_summary_3_meta_50) %>%
  bind_rows(sim_summary_3_meta_60) %>%
  bind_rows(sim_summary_3_meta_70) %>%
  bind_rows(sim_summary_3_meta_80) %>%
  bind_rows(sim_summary_3_meta_90) %>%
  bind_rows(sim_summary_3_meta_180) %>%
  bind_rows(sim_summary_3_meta_110) %>%
  bind_rows(sim_summary_3_meta_120) %>%
  bind_rows(sim_summary_3_meta_130) %>%
  bind_rows(sim_summary_3_meta_150) %>%
  bind_rows(sim_summary_3_meta_220) %>%
  bind_rows(sim_summary_3_meta_270) %>%
  bind_rows(sim_summary_3_meta_365) %>%
  mutate(immunity_duration = 1/omega) %>%
  arrange(immunity_duration) %>%
  mutate(model = "meta",
         patches = 3)

write_csv(waning_results_3, file = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/waning_results_3.csv")

waning_results_3
NA
ggplot(waning_results_3, aes(immunity_duration, sum_persist)) +
  geom_line()+
  geom_point()+
  theme_bw()

14 Metapopulation Model

###Set-up

# Define Paramenters
patchPopSize_14 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Patch size
U <- length(patchPopSize_14)                    # Number of patches
initial_infected <-  as.vector(rmultinom(1, 1, rep(0.5, U)))   # Initial infected (initial infected patch randomly generated)
initial_infected_patch <- which(initial_infected > 0)
simName <- "SIRS metapopulation model"       # Simulation name
tf <- 365*3                                   # Final time

# Agta Hunter-Gatherer contact rates
within_pop_contact = 1
between_pop_contact = 0.5/U     # normalised by number of patches 

#Create the named initial state vector for the U-patch system.

x0_14_meta <- unlist(lapply(
  seq_len(U), 
  function(i){ 
    c(patchPopSize_14[i] - initial_infected[i], initial_infected[i], 0, 0, patchPopSize_14[i])
  }
))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(i) paste0(c("S","E","I", "R", "N"), i)))


# Define the state change matrix for a single patch
nu_14_meta <- matrix(c( -1,  0,  0, +1, +1, -1,  0,  0,  0,  0, # S
                     +1, -1,  0,  0,  0,  0, -1,  0,  0,  0, # E
                      0, +1, -1,  0,  0,  0,  0, -1,  0, -1, # I
                      0,  0, +1, -1,  0,  0,  0,  0, -1,  0, # R 
                      0,  0,  0,  0, +1, -1 ,-1, -1, -1, -1), # N
             nrow=5,byrow=TRUE)

# Define propensity functions
# Mass-action
a_14_meta <-
  unlist(lapply(
    seq_len(U),
    function(patch) {
      i <- patch
      patches <- 1:U
      #j <- if (patch == 1) U else patch - 1
      other_patches <- patches[-i]
      patch_beta <- c()
      for(k in (1:(U-1))){
        patch_beta[k] = paste0("+(beta_", other_patches[k],i, "*I", other_patches[k], "/N", other_patches[k], ")*S", i)
      }
      c(
        paste0("(beta_", i, i, "*I", i,"/N", i, ")*S",i, paste0(patch_beta, collapse="")), # Infection
        paste0("sigma*E", i),                                       # Becomes infecious
        paste0("gamma*I", i),                                       # Recovery from infection
        paste0("omega*R", i),       # Loss of immunity
        paste0("mu*N", i),                             # Births
        paste0("mu*S", i),                                             # Deaths (S)
        paste0("mu*E", i),                                             # Deaths (E)
        paste0("mu*I", i),                                             # Deaths (I)
        paste0("mu*R", i),                                             # Deaths (R)
        paste0("alpha*I", i)                                           # Deaths from infection
        
      )
    }
  ))

Metapopulation Model

#Collect parameters
parms_14_meta <- list(
  sigma = 0.175,                          # E to I rate
  gamma = 0.2,                           # I to R rate
  omega = 1/100,                         # R to S rate
  mu = demo_sum$Birth_rate_daily_Mean,                            # Birth/death rate per person per day
  alpha = 1/1000) 

# Define transmission terms and populate next-generation matrix
beta <- 0.6

nextgen_14_matrix <- matrix(nrow = U, ncol = U, data = 0)
beta_14_matrix <- matrix(nrow = U, ncol = U, data = 0)


for(i in 1:U){
  for(j in 1:U){
    parms_14_meta[[paste0("beta_",i,i)]] = within_pop_contact*beta
    nextgen_14_matrix[i,i] = within_pop_contact*beta*(1/parms_14_meta$gamma)
    parms_14_meta[[paste0("beta_",j,i)]] = between_pop_contact*beta
    nextgen_14_matrix[j,i] = between_pop_contact*beta*(1/parms_14_meta$gamma)
    nextgen_14_matrix[i,j] = between_pop_contact*beta*(1/parms_14_meta$gamma)
    parms_14_meta[[paste0("beta_",j,j)]] = within_pop_contact*beta
    nextgen_14_matrix[j,j] = within_pop_contact*beta*(1/parms_14_meta$gamma)
    beta_14_matrix[i,i] = within_pop_contact*beta
    beta_14_matrix[j,i] = between_pop_contact*beta
    beta_14_matrix[i,j] = between_pop_contact*beta
    beta_14_matrix[j,j] = within_pop_contact*beta
  }
  parms_14_meta[[paste0("N", i)]] = patchPopSize_14[i]
}
# Run simulations with the Direct method
set.seed(25)
out_14_meta <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Plot
plot_data_14_meta <- out_14_meta$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta <- ggplot(data = plot_data_14_meta, aes(x=t, y=count, colour=state))+
  geom_line(alpha=0.8)+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 1, scales = "free_y")+
  labs(x="Time (Days)",
       y="Number of Individuals",
       colour="State")+
  theme_bw()
plot_14_meta

ggsave(filename = "meta_3_plot.pdf", 
       plot = plot_14_meta,
       device = "pdf",
       width = 7, 
       height = 8,
       path = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models")

## Table showing extinction/transmission info for each patch

extinct_data_14_meta <- out_14_meta$data %>%
  as_tibble() %>%
  slice_max(t) %>%
  distinct() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N")),
         persist = case_when(state=="I" & count > 0 ~ T, 
                             state=="I" & count == 0 ~ F)) %>%
  drop_na() %>%
  select(patch, count, persist)
extinct_data_14_meta
beta_14_meta <- beta.ngm(beta_14_matrix)
paste0("Beta for whole system = ", beta_14_meta)
[1] "Beta for whole system = 0.878571428571429"
R0_14_meta <- R0ngm(nextgen_14_matrix)
paste0("R0 = ", R0_14_meta)
[1] "R0 = 4.39285714285715"
paste0("Actual number of infecteds at end of sim = ", sum(extinct_data_14_meta$count))
[1] "Actual number of infecteds at end of sim = 15"
 # Total number of infecteds at the end of sim across all patches

sim_endpoint_14_meta <- as_tibble(out_14_meta$data) %>%
  slice_max(t) %>%
  distinct()


paste0("Did simulation run reach final endpoint?")
[1] "Did simulation run reach final endpoint?"
if (sim_endpoint_14_meta$t >= tf) {
  print("Yes")
} else {
  print("No")}
[1] "Yes"
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta <- list()
sim_list_14_meta <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_14 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(lapply(
  seq_len(U), 
  function(x){ 
    c(patchPopSize_14[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_14[x])
  }
))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))
  
  out_100_14_meta <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta <- out_100_14_meta$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta[[i]] <- sim_data_14_meta
}

sim_output_14_meta <- bind_rows(sim_list_14_meta)
# Summary table of endpoint data
sim_output_14_meta <- sim_output_14_meta %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta
# Make Summary Table of output
sim_summary_14_meta <- sim_output_14_meta %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/100)
sim_summary_14_meta

Varying waining immunity

0 Days

#Collect parameters
parms_14_meta_0 <- parms_14_meta
parms_14_meta_0$omega <- 0


# Run simulations with the Direct method
set.seed(4)
out_14_meta_0 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_0,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_0 <- out_14_meta_0$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_0 <- ggplot(data = plot_data_14_meta_0, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_0

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_0 <- list()
sim_list_14_meta_0 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_0 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_0,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_0 <- out_100_14_meta_0$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_0[[i]] <- sim_data_14_meta_0
}

sim_output_14_meta_0 <- bind_rows(sim_list_14_meta_0)
# Summary table of endpoint data
sim_output_14_meta_0 <- sim_output_14_meta_0 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_0

# Make Summary Table of output
sim_summary_14_meta_0 <- sim_output_14_meta_0 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 0)
sim_summary_14_meta_0

10 Days

#Collect parameters
parms_14_meta_10 <- parms_14_meta
parms_14_meta_10$omega <- 1/10

# Run simulations with the Direct method
set.seed(4)
out_14_meta_10 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_10,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_10 <- out_14_meta_10$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_10 <- ggplot(data = plot_data_14_meta_10, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_10

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_10 <- list()
sim_list_14_meta_10 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_10 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_10,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_10 <- out_100_14_meta_10$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_10[[i]] <- sim_data_14_meta_10
}

sim_output_14_meta_10 <- bind_rows(sim_list_14_meta_10)
# Summary table of endpoint data
sim_output_14_meta_10 <- sim_output_14_meta_10 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))

# Make Summary Table of output
sim_summary_14_meta_10 <- sim_output_14_meta_10 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/10)
sim_summary_14_meta_10

20 Days

#Collect parameters
parms_14_meta_20 <- parms_14_meta
parms_14_meta_20$omega <- 1/20


# Run simulations with the Direct method
set.seed(4)
out_14_meta_20 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_20,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_20 <- out_14_meta_20$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_20 <- ggplot(data = plot_data_14_meta_20, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_20

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_20 <- list()
sim_list_14_meta_20 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_20 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_20,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_20 <- out_100_14_meta_20$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_20[[i]] <- sim_data_14_meta_20
}

sim_output_14_meta_20 <- bind_rows(sim_list_14_meta_20)
# Summary table of endpoint data
sim_output_14_meta_20 <- sim_output_14_meta_20 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_20

# Make Summary Table of output
sim_summary_14_meta_20 <- sim_output_14_meta_20 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/20)
sim_summary_14_meta_20

30 Days

#Collect parameters
parms_14_meta_30 <- parms_14_meta
parms_14_meta_30$omega <- 1/30


# Run simulations with the Direct method
set.seed(4)
out_14_meta_30 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_30,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_30 <- out_14_meta_30$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_30 <- ggplot(data = plot_data_14_meta_30, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_30

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_30 <- list()
sim_list_14_meta_30 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_30 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_30,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_30 <- out_100_14_meta_30$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_30[[i]] <- sim_data_14_meta_30
}

sim_output_14_meta_30 <- bind_rows(sim_list_14_meta_30)
# Summary table of endpoint data
sim_output_14_meta_30 <- sim_output_14_meta_30 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_30

# Make Summary Table of output
sim_summary_14_meta_30 <- sim_output_14_meta_30 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/30)
sim_summary_14_meta_30

40 Days

#Collect parameters
parms_14_meta_40 <- parms_14_meta
parms_14_meta_40$omega <- 1/40


# Run simulations with the Direct method
set.seed(4)
out_14_meta_40 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_40,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_40 <- out_14_meta_40$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_40 <- ggplot(data = plot_data_14_meta_40, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_40

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_40 <- list()
sim_list_14_meta_40 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_40 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_40,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_40 <- out_100_14_meta_40$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_40[[i]] <- sim_data_14_meta_40
}

sim_output_14_meta_40 <- bind_rows(sim_list_14_meta_40)
# Summary table of endpoint data
sim_output_14_meta_40 <- sim_output_14_meta_40 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_40

# Make Summary Table of output
sim_summary_14_meta_40 <- sim_output_14_meta_40 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/40)
sim_summary_14_meta_40

50 Days

#Collect parameters
parms_14_meta_50 <- parms_14_meta
parms_14_meta_50$omega <- 1/50


# Run simulations with the Direct method
set.seed(4)
out_14_meta_50 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_50,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_50 <- out_14_meta_50$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_50 <- ggplot(data = plot_data_14_meta_50, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_50

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_50 <- list()
sim_list_14_meta_50 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_50 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_50,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_50 <- out_100_14_meta_50$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_50[[i]] <- sim_data_14_meta_50
}

sim_output_14_meta_50 <- bind_rows(sim_list_14_meta_50)
# Summary table of endpoint data
sim_output_14_meta_50 <- sim_output_14_meta_50 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_50

# Make Summary Table of output
sim_summary_14_meta_50 <- sim_output_14_meta_50 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/50)
sim_summary_14_meta_50

60 Days

#Collect parameters
parms_14_meta_60 <- parms_14_meta
parms_14_meta_60$omega <- 1/60


# Run simulations with the Direct method
set.seed(4)
out_14_meta_60 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_60,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_60 <- out_14_meta_60$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_60 <- ggplot(data = plot_data_14_meta_60, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_60

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_60 <- list()
sim_list_14_meta_60 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_60 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_60,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_60 <- out_100_14_meta_60$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_60[[i]] <- sim_data_14_meta_60
}

sim_output_14_meta_60 <- bind_rows(sim_list_14_meta_60)
# Summary table of endpoint data
sim_output_14_meta_60 <- sim_output_14_meta_60 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_60

# Make Summary Table of output
sim_summary_14_meta_60 <- sim_output_14_meta_60 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/60)
sim_summary_14_meta_60

70 Days

#Collect parameters
parms_14_meta_70 <- parms_14_meta
parms_14_meta_70$omega <- 1/70


# Run simulations with the Direct method
set.seed(4)
out_14_meta_70 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_70,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_70 <- out_14_meta_70$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_70 <- ggplot(data = plot_data_14_meta_70, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_70

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_70 <- list()
sim_list_14_meta_70 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_70 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_70,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_70 <- out_100_14_meta_70$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_70[[i]] <- sim_data_14_meta_70
}

sim_output_14_meta_70 <- bind_rows(sim_list_14_meta_70)
# Summary table of endpoint data
sim_output_14_meta_70 <- sim_output_14_meta_70 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_70

# Make Summary Table of output
sim_summary_14_meta_70 <- sim_output_14_meta_70 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/70)
sim_summary_14_meta_70

80 Days

#Collect parameters
parms_14_meta_80 <- parms_14_meta
parms_14_meta_80$omega <- 1/80


# Run simulations with the Direct method
set.seed(4)
out_14_meta_80 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_80,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_80 <- out_14_meta_80$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_80 <- ggplot(data = plot_data_14_meta_80, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_80

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_80 <- list()
sim_list_14_meta_80 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_80 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_80,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_80 <- out_100_14_meta_80$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_80[[i]] <- sim_data_14_meta_80
}

sim_output_14_meta_80 <- bind_rows(sim_list_14_meta_80)
# Summary table of endpoint data
sim_output_14_meta_80 <- sim_output_14_meta_80 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_80

# Make Summary Table of output
sim_summary_14_meta_80 <- sim_output_14_meta_80 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/80)
sim_summary_14_meta_80

90 Days

#Collect parameters
parms_14_meta_90 <- parms_14_meta
parms_14_meta_90$omega <- 1/90


# Run simulations with the Direct method
set.seed(4)
out_14_meta_90 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_90,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_90 <- out_14_meta_90$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_90 <- ggplot(data = plot_data_14_meta_90, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_90

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_90 <- list()
sim_list_14_meta_90 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_90 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_90,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_90 <- out_100_14_meta_90$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_90[[i]] <- sim_data_14_meta_90
}

sim_output_14_meta_90 <- bind_rows(sim_list_14_meta_90)
# Summary table of endpoint data
sim_output_14_meta_90 <- sim_output_14_meta_90 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_90

# Make Summary Table of output
sim_summary_14_meta_90 <- sim_output_14_meta_90 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/90)
sim_summary_14_meta_90

180 Days

#Collect parameters
parms_14_meta_180 <- parms_14_meta
parms_14_meta_180$omega <- 1/180


# Run simulations with the Direct method
set.seed(20)
out_14_meta_180 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_180,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_180 <- out_14_meta_180$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_180 <- ggplot(data = plot_data_14_meta_180, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_180

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_180 <- list()
sim_list_14_meta_180 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_180 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_180,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_180 <- out_100_14_meta_180$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_180[[i]] <- sim_data_14_meta_180
}

sim_output_14_meta_180 <- bind_rows(sim_list_14_meta_180)
# Summary table of endpoint data
sim_output_14_meta_180 <- sim_output_14_meta_180 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_180

# Make Summary Table of output
sim_summary_14_meta_180 <- sim_output_14_meta_180 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/180)
sim_summary_14_meta_180

110 Days

#Collect parameters
parms_14_meta_110 <- parms_14_meta
parms_14_meta_110$omega <- 1/110


# Run simulations with the Direct method
set.seed(4)
out_14_meta_110 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_110,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_110 <- out_14_meta_110$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_110 <- ggplot(data = plot_data_14_meta_110, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_110

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_110 <- list()
sim_list_14_meta_110 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_110 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_110,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_110 <- out_100_14_meta_110$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_110[[i]] <- sim_data_14_meta_110
}

sim_output_14_meta_110 <- bind_rows(sim_list_14_meta_110)
# Summary table of endpoint data
sim_output_14_meta_110 <- sim_output_14_meta_110 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_110

# Make Summary Table of output
sim_summary_14_meta_110 <- sim_output_14_meta_110 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/110)
sim_summary_14_meta_110

120 Days

#Collect parameters
parms_14_meta_120 <- parms_14_meta
parms_14_meta_120$omega <- 1/120


# Run simulations with the Direct method
set.seed(4)
out_14_meta_120 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_120,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_120 <- out_14_meta_120$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_120 <- ggplot(data = plot_data_14_meta_120, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_120

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_120 <- list()
sim_list_14_meta_120 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_120 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_120,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_120 <- out_100_14_meta_120$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_120[[i]] <- sim_data_14_meta_120
}

sim_output_14_meta_120 <- bind_rows(sim_list_14_meta_120)
# Summary table of endpoint data
sim_output_14_meta_120 <- sim_output_14_meta_120 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_120

# Make Summary Table of output
sim_summary_14_meta_120 <- sim_output_14_meta_120 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/120)
sim_summary_14_meta_120

130 Days

#Collect parameters
parms_14_meta_130 <- parms_14_meta
parms_14_meta_130$omega <- 1/130


# Run simulations with the Direct method
set.seed(4)
out_14_meta_130 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_130,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_130 <- out_14_meta_130$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_130 <- ggplot(data = plot_data_14_meta_130, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_130

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_130 <- list()
sim_list_14_meta_130 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_130 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_130,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_130 <- out_100_14_meta_130$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_130[[i]] <- sim_data_14_meta_130
}

sim_output_14_meta_130 <- bind_rows(sim_list_14_meta_130)
# Summary table of endpoint data
sim_output_14_meta_130 <- sim_output_14_meta_130 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_130

# Make Summary Table of output
sim_summary_14_meta_130 <- sim_output_14_meta_130 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/130)
sim_summary_14_meta_130

150 Days

#Collect parameters
parms_14_meta_150 <- parms_14_meta
parms_14_meta_150$omega <- 1/150


# Run simulations with the Direct method
set.seed(4)
out_14_meta_150 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_150,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_150 <- out_14_meta_150$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_150 <- ggplot(data = plot_data_14_meta_150, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_150

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_150 <- list()
sim_list_14_meta_150 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_150 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_150,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_150 <- out_100_14_meta_150$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_150[[i]] <- sim_data_14_meta_150
}

sim_output_14_meta_150 <- bind_rows(sim_list_14_meta_150)
# Summary table of endpoint data
sim_output_14_meta_150 <- sim_output_14_meta_150 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_150

# Make Summary Table of output
sim_summary_14_meta_150 <- sim_output_14_meta_150 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/150)
sim_summary_14_meta_150

220 Days

#Collect parameters
parms_14_meta_220 <- parms_14_meta
parms_14_meta_220$omega <- 1/220


# Run simulations with the Direct method
set.seed(4)
out_14_meta_220 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_220,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_220 <- out_14_meta_220$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_220 <- ggplot(data = plot_data_14_meta_220, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_220

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_220 <- list()
sim_list_14_meta_220 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_220 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_220,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_220 <- out_100_14_meta_220$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_220[[i]] <- sim_data_14_meta_220
}

sim_output_14_meta_220 <- bind_rows(sim_list_14_meta_220)
# Summary table of endpoint data
sim_output_14_meta_220 <- sim_output_14_meta_220 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_220

# Make Summary Table of output
sim_summary_14_meta_220 <- sim_output_14_meta_220 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/220)
sim_summary_14_meta_220

270 Days

#Collect parameters
parms_14_meta_270 <- parms_14_meta
parms_14_meta_270$omega <- 1/270


# Run simulations with the Direct method
set.seed(4)
out_14_meta_270 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_270,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_270 <- out_14_meta_270$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_270 <- ggplot(data = plot_data_14_meta_270, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_270

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_270 <- list()
sim_list_14_meta_270 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_270 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_270,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_270 <- out_100_14_meta_270$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_270[[i]] <- sim_data_14_meta_270
}

sim_output_14_meta_270 <- bind_rows(sim_list_14_meta_270)
# Summary table of endpoint data
sim_output_14_meta_270 <- sim_output_14_meta_270 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_270

# Make Summary Table of output
sim_summary_14_meta_270 <- sim_output_14_meta_270 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/270)
sim_summary_14_meta_270

365 Days

#Collect parameters
parms_14_meta_365 <- parms_14_meta
parms_14_meta_365$omega <- 1/365


# Run simulations with the Direct method
set.seed(4)
out_14_meta_365 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_365,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_365 <- out_14_meta_365$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_365 <- ggplot(data = plot_data_14_meta_365, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_365

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_365 <- list()
sim_list_14_meta_365 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_365 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_365,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_365 <- out_100_14_meta_365$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_365[[i]] <- sim_data_14_meta_365
}

sim_output_14_meta_365 <- bind_rows(sim_list_14_meta_365)
# Summary table of endpoint data
sim_output_14_meta_365 <- sim_output_14_meta_365 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_365

# Make Summary Table of output
sim_summary_14_meta_365 <- sim_output_14_meta_365 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/365)
sim_summary_14_meta_365

Results

waning_results_14 <- sim_summary_14_meta %>%
  bind_rows(sim_summary_14_meta_10) %>%
  bind_rows(sim_summary_14_meta_20) %>%
  bind_rows(sim_summary_14_meta_30) %>%
  bind_rows(sim_summary_14_meta_40) %>%
  bind_rows(sim_summary_14_meta_50) %>%
  bind_rows(sim_summary_14_meta_60) %>%
  bind_rows(sim_summary_14_meta_70) %>%
  bind_rows(sim_summary_14_meta_80) %>%
  bind_rows(sim_summary_14_meta_90) %>%
  bind_rows(sim_summary_14_meta_180) %>%
  bind_rows(sim_summary_14_meta_110) %>%
  bind_rows(sim_summary_14_meta_120) %>%
  bind_rows(sim_summary_14_meta_130) %>%
  bind_rows(sim_summary_14_meta_150) %>%
  bind_rows(sim_summary_14_meta_220) %>%
  bind_rows(sim_summary_14_meta_270) %>%
  bind_rows(sim_summary_14_meta_365) %>%
  mutate(immunity_duration = 1/omega) %>%
  arrange(immunity_duration) %>%
  mutate(model = "meta",
         patches = 14)

write_csv(waning_results_14, file = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/waning_results_14.csv")

waning_results_14
NA
ggplot(waning_results_14, aes(immunity_duration, sum_persist)) +
  geom_line()+
  geom_point()+
  theme_bw()

Combined Results

combined_waning

combined_waning
combined_plot <- ggplot(combined_waning, aes(immunity_duration, sum_persist, colour = as.factor(patches)))+
  geom_line(alpha=0.7, size=1)+
  geom_point(alpha=0.5, size=2)+
  geom_segment(x = -Inf, y = 50, xend = 141.5, yend = 50, linetype = "dashed", colour = "grey") +
  geom_segment(x = 5, y = 50, xend = 5, yend = -Inf, linetype = "dashed", colour = "grey") +
  geom_segment(x = 42.5, y = 50, xend = 42.5, yend = -Inf, linetype = "dashed", colour = "grey") +
  geom_segment(x = 91.5, y = 50, xend = 91.5, yend = -Inf, linetype = "dashed", colour = "grey") +
  geom_segment(x = 141.5, y = 50, xend = 141.5, yend = -Inf, linetype = "dashed", colour = "grey") +
  scale_y_continuous(breaks = seq(0, 100, 10)) +
  scale_x_continuous(breaks = seq(0, 360, 50)) +
  labs(x = "Duration of immunity (days)",
       y = "Probability of persistence after 3 years (%)", 
       colour = "No. Patches")+
  scale_color_discrete(type = wes_palettes$Zissou1[2:5],
                       labels = c("1", "3", "7", "14"))+
  theme_bw()

combined_plot

ggsave(filename = "combined_plot_patches.pdf", plot = combined_plot, device = "pdf", width = 7, height = 5, path = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models")

LS0tCnRpdGxlOiAiTW9kZWxsaW5nIHRoZSBwZXJzaXN0ZW5jZSBvZiBpbmZlY3Rpb3VzIGRpc2Vhc2VzIGluIHByZS1hZ3JpY3VsdHVyYWwgSHVudGVyLWdhdGhlcmVycyIKc3VidGl0bGU6ICJDb25kZW5zZWQgUmVwb3J0IgphdXRob3I6ICJNYXR0aGV3IEhveWxlIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCiMjIFNldC11cApgYGB7cn0KIyBybShsaXN0ID0gbHMoKSkKbGlicmFyeShkcGx5cikKbGlicmFyeSh3ZXNhbmRlcnNvbikKbGlicmFyeShHaWxsZXNwaWVTU0EpCmxpYnJhcnkodGlkeXZlcnNlKQpgYGAKCiMjIE1vZGVsIFBhcmFtZXRlciBlc3RpbWF0aW9uCgojIyMgQWd0YSBIdW50ZXItR2F0aGVyZXIgRGVtb2dyYXBoeQoKSW5mb3JtYXRpb24gcmVnYXJkaW5nIGJpcnRocywgZGVhdGhzIGFuZCBwb3B1bGF0aW9uIHNpemUgd2VyZSBvYnRhaW4gZnJvbSBhIHN0dWR5IGNvbmR1Y3RlZCBieSBIZWFkbGFuZCBldCBhbC4sICgyMDExKS4gQXV0aG9ycyBjb25kdWN0ZWQgYSBjZW5zdXMtbGlrZSBzdXJ2ZXkgb2YgdGhlIApgYGB7cn0KYWd0YV9kZW1vIDwtIHJlYWQuY3N2KCJBZ3RhUG9wRHluYW1pY3NfSGVhZGxhbmQyMDA3LmNzdiIpCgpnZ3Bsb3QoYWd0YV9kZW1vLCBhZXMoeD1ZZWFyKSkgKwogIGdlb21fbGluZShhZXMoeT1Qb3BTaXplKSwgY29sb3VyID0gd2VzX3BhbGV0dGVzJERhcmplZWxpbmcxWzFdKSArCiAgZ2VvbV9saW5lKGFlcyh5PUJpcnRocyksIGNvbG91ciA9IHdlc19wYWxldHRlcyREYXJqZWVsaW5nMVsyXSkgKwogIGdlb21fbGluZShhZXMoeT1EZWF0aHMpLCBjb2xvdXIgPSB3ZXNfcGFsZXR0ZXMkRGFyamVlbGluZzFbM10pICsKICB0aGVtZV9idygpCmBgYAoKIyMjIyBQb3B1bGF0aW9uIFNpemUKYGBge3J9Cmhpc3QoYWd0YV9kZW1vJFBvcFNpemUpCnN1bW1hcnkoYWd0YV9kZW1vJFBvcFNpemUpCmBgYAoKIyMjIyBCaXJ0aHMKYGBge3J9Cmhpc3QoYWd0YV9kZW1vJEJpcnRocykKc3VtbWFyeShhZ3RhX2RlbW8kQmlydGhzKQpgYGAKCiMjIyMgRGVhdGhzCmBgYHtyfQpoaXN0KGFndGFfZGVtbyREZWF0aHMpCnN1bW1hcnkoYWd0YV9kZW1vJERlYXRocykKYGBgCgojIyMjIEJpcnRoL0RlYXRoIHJhdGUgcGVyIHBlcnNvbiBwZXIgZGF5CmBgYHtyIHdhcm5pbmc9RkFMU0V9CmFndGFfZGVtbyA8LSBhZ3RhX2RlbW8gJT4lCiAgbXV0YXRlKEJpcnRoX3JhdGUgPSBCaXJ0aHMvKEZlbWFsZSoyKSwKICAgICAgICAgQmlydGhfcmF0ZV9kYWlseSA9ICgxICsgQmlydGhfcmF0ZSkgXiAoMS8zNjUpIC0gMSwKICAgICAgICAgRGVhdGhfcmF0ZSA9IChEZWF0aHMvUG9wU2l6ZSksCiAgICAgICAgIERlYXRoX3JhdGVfZGFpbHkgPSAoMSArIERlYXRoX3JhdGUpIF4gKDEvMzY1KSAtIDEsCiAgICAgICAgIFBvcENoYW5nZSA9IChkaWZmID0gUG9wU2l6ZSAtIGxhZyhQb3BTaXplLCBkZWZhdWx0ID0gZmlyc3QoUG9wU2l6ZSkpKSwKICAgICAgICAgUG9wQ2hhbmdlX3JhdGUgPSBhYnMoUG9wQ2hhbmdlKS9Qb3BTaXplLAogICAgICAgICBQb3BDaGFuZ2VfcmF0ZV9kYWlseSA9ICgxICsgUG9wQ2hhbmdlX3JhdGUpIF4gKDEvMzY1KSAtIDEpCmhlYWQoYWd0YV9kZW1vKQoKCmhpc3QoYWd0YV9kZW1vJEJpcnRoX3JhdGUpCmhpc3QoYWd0YV9kZW1vJERlYXRoX3JhdGUpCgpnZ3Bsb3QoYWd0YV9kZW1vLCBhZXMoeD1ZZWFyKSkgKwogIGdlb21fbGluZShhZXMoeT1CaXJ0aF9yYXRlKSwgY29sb3VyID0gd2VzX3BhbGV0dGVzJERhcmplZWxpbmcxWzJdKSArCiAgZ2VvbV9saW5lKGFlcyh5PURlYXRoX3JhdGUpLCBjb2xvdXIgPSB3ZXNfcGFsZXR0ZXMkRGFyamVlbGluZzFbM10pICsKICB0aGVtZV9idygpCgpkZW1vX3N1bSA8LSBhZ3RhX2RlbW8gJT4lCiAgc2VsZWN0KFBvcFNpemUsIEJpcnRoX3JhdGUsIEJpcnRoX3JhdGVfZGFpbHksIERlYXRoX3JhdGUsIERlYXRoX3JhdGVfZGFpbHksIFBvcENoYW5nZV9yYXRlLCBQb3BDaGFuZ2VfcmF0ZV9kYWlseSkgJT4lCiAgICBzdW1tYXJpc2UoYWNyb3NzKAogICAgLmNvbHMgPSBpcy5udW1lcmljLCAKICAgIC5mbnMgPSBsaXN0KE1lYW4gPSBtZWFuLCBTRCA9IHNkKSwgbmEucm0gPSBUUlVFLCAKICAgIC5uYW1lcyA9ICJ7Y29sfV97Zm59IgogICAgKSkKZGVtb19zdW0gCgpkZW1vX3N1bSA8LSBhcy5saXN0KGRlbW9fc3VtKQpgYGAKCiMjIyBBZ3RhIEJhbmQgU2l6ZQpgYGB7cn0KIyBJbXBvcnQgQ2FtcCBkYXRhIGZyb20gTWFyayBEeWJsZQpjYW1wcy5kYXRhIDwtIHJlYWRfY3N2KCJjYW1wcy5jc3YiKQoKaGVhZChjYW1wcy5kYXRhKQpgYGAKCgpgYGB7cn0KIyBFeHBsb3JlIGNhbXAgc2l6ZQpoaXN0KGNhbXBzLmRhdGEkY2FtcF90b3RhbCkKCmNhbXAuc2l6ZSA8LSBjYW1wcy5kYXRhICU+JQogIHN1bW1hcmlzZShtZWFuID0gbWVhbihjYW1wX3RvdGFsKSwKICAgICAgICAgICAgc2QgPSBzZChjYW1wX3RvdGFsKSwKICAgICAgICAgICAgbWluID0gbWluKGNhbXBfdG90YWwpLAogICAgICAgICAgICBtYXggPSBtYXgoY2FtcF90b3RhbCksCiAgICAgICAgICAgIHZhciA9IHZhcihjYW1wX3RvdGFsKSkKY2FtcC5zaXplCmBgYAoKCiMjIFNpbmdsZSBQb3B1bGF0aW9uIE1vZGVsCgojIyMgU2V0LXVwCgpgYGB7cn0KIyBEZWZpbmUgUGFyYW1lbnRlcnMKTiA8LSAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxKSAgICAjIFBvcHVsYXRpb24gc2l6ZQppbml0aWFsX2luZmVjdGVkIDwtICAxICAgICMgSW5pdGlhbCBpbmZlY3RlZApzaW1OYW1lIDwtICJTRUlSUyBtb2RlbCIgICAgICAgIyBTaW11bGF0aW9uIG5hbWUKdGYgPC0gMzY1KjMKCiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXMgPC0gbGlzdCgKICBiZXRhID0gMC42LAogIHNpZ21hID0gMC4xNzUsICAgICAgICAgICAgICAgICAgICAgICAgICAjIEUgdG8gSSByYXRlCiAgZ2FtbWEgPSAwLjIsICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBJIHRvIFIgcmF0ZQogIG9tZWdhID0gMS8xMDAsICAgICAgICAgICAgICAgICAgICAgICAgICMgUiB0byBTIHJhdGUKICBtdSA9IGRlbW9fc3VtJEJpcnRoX3JhdGVfZGFpbHlfTWVhbiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBCaXJ0aC9kZWF0aCByYXRlIHBlciBwZXJzb24gcGVyIGRheQogIGFscGhhID0gMS8xMDAwKSAKCiNDcmVhdGUgdGhlIG5hbWVkIGluaXRpYWwgc3RhdGUgdmVjdG9yIGZvciB0aGUgVS1wYXRjaCBzeXN0ZW0uCgp4MCA8LSBjKE4gLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOKQoKbmFtZXMoeDApIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiMgRGVmaW5lIHRoZSBzdGF0ZSBjaGFuZ2UgbWF0cml4IGZvciBhIHNpbmdsZSBwYXRjaApudSA8LSBtYXRyaXgoYyggLTEsICAwLCAgMCwgKzEsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsICMgUwogICAgICAgICAgICAgICAgKzEsIC0xLCAgMCwgIDAsICAwLCAgMCwgLTEsICAwLCAgMCwgIDAsICMgRQogICAgICAgICAgICAgICAgMCwgKzEsIC0xLCAgMCwgIDAsICAwLCAgMCwgLTEsICAwLCAtMSwgIyBJCiAgICAgICAgICAgICAgICAwLCAgMCwgKzEsIC0xLCAgMCwgIDAsICAwLCAgMCwgLTEsICAwLCAjIFIgCiAgICAgICAgICAgICAgICAwLCAgMCwgIDAsICAwLCArMSwgLTEgLC0xLCAtMSwgLTEsIC0xKSwgIyBOCiAgICAgICAgICAgICBucm93PTUsYnlyb3c9VFJVRSkKCiMgRGVmaW5lIHByb3BlbnNpdHkgZnVuY3Rpb25zCmEgPC1jKAogICAgICAgIHBhc3RlMCgiKGJldGEqSS9OKSpTIiksICMgSW5mZWN0aW9uCiAgICAgICAgcGFzdGUwKCJzaWdtYSpFIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBCZWNvbWVzIGluZmVjaW91cwogICAgICAgIHBhc3RlMCgiZ2FtbWEqSSIpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgUmVjb3ZlcnkgZnJvbSBpbmZlY3Rpb24KICAgICAgICBwYXN0ZTAoIm9tZWdhKlIiKSwgICAgICAgIyBMb3NzIG9mIGltbXVuaXR5CiAgICAgICAgcGFzdGUwKCJtdSpOIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEJpcnRocwogICAgICAgIHBhc3RlMCgibXUqUyIpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIChTKQogICAgICAgIHBhc3RlMCgibXUqRSIpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIChFKQogICAgICAgIHBhc3RlMCgibXUqSSIpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIChJKQogICAgICAgIHBhc3RlMCgibXUqUiIpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIChSKQogICAgICAgIHBhc3RlMCgiYWxwaGEqSSIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIGZyb20gaW5mZWN0aW9uCiAgICAgICAgCiAgICAgICkKCmBgYAoKRGVmaW5lIGZ1bmN0aW9ucyB0byBjYWxjdWxhdGUgUjAgYW5kIGV4cGVjdGVkIG51bWJlciBvZiBzdXNjZXB0aWJsZXMgYXQgZXF1aWxpYnJpdW0sIGFuZCBjcml0aWNhbCBjb21tdW5pdHkgc2l6ZSAoRGlla21hbm4gZXQgYWwuLCAyMDEyKS4KCmBgYHtyfQogUjAgPC0gZnVuY3Rpb24ocGFybXMpIHsKICAgKHBhcm1zJHNpZ21hLyhwYXJtcyRzaWdtYSArIHBhcm1zJG11KSkgKiAocGFybXMkYmV0YS9wYXJtcyRnYW1tYSArIHBhcm1zJG11ICsgcGFybXMkYWxwaGEpCiB9IAogIApFSUUgPC0gZnVuY3Rpb24oUjAsIHBhcm1zKSB7CiAgeSA9ICgoUjAgLSAxKSAqIHBhcm1zJG9tZWdhKSAvIChwYXJtcyRnYW1tYSAqIFIwKQogIHJldHVybih5KQp9CgpDQ1MgPC0gZnVuY3Rpb24oZXBzaWxvbiwgUjApIHsKICB5ID0gMS8oKGVwc2lsb25eMikqKCgxLSgxL1IwKSleMikpCiAgcmV0dXJuKHkpCn0KYGBgCgojIyMgU2luZ2xlIFBvcHVsYXRpb24gTW9kZWwKYGBge3J9CgojIENhbGN1bGF0ZSBSMCwgZXhwZWN0ZWQgbnVtYmVyIG9mIGluZmVjdGVkcyBhdCBlcXVpbGlicml1bSwgbWFnbml0dWRlIG9mIG9zY2lsbGF0aW9uIGFuZCBDQ1MKUjBfc2luZ2xlIDwtIFIwKHBhcm1zKQpSMF9zaW5nbGUKCkVJRV9zaW5nbGUgPC0gRUlFKFIwX3NpbmdsZSwgcGFybXMpICMgcHJvcG9ydGlvbiBvZiBleHBlY3RlZCBpbmZlY3RlZHMgYXQgZXF1aWxpYnJpdW0KRUlFX3NpbmdsZQoKZXhwZXh0ZWRfaW5mZWN0ZWRzIDwtIEVJRV9zaW5nbGUqTiAjIG51bWJlciBvZiBleHBlY3RlZCBpbmZlY3RlZHMgYXQgZXF1aWxpYnJpdW0KZXhwZXh0ZWRfaW5mZWN0ZWRzCgpzcXJ0KE4pICMgbWFnbml0dWRlIG9mIG9zY2lsbGF0aW9ucyAKCmVwc2lsb24gPC0gKDUuNy8zNjUpLzIzICMgZHVyYXRpb24gb2YgaW5mZWN0aW9uIGluIHllYXJzIGRpdmlkZWQgYnkgYXZnIGxpZmUgZXhwZWN0YW5jeSAKQ0NTX3NpbmdsZSA8LSBDQ1MoZXBzaWxvbiwgUjBfc2luZ2xlKSAjIEF2ZXJhZ2UgbGlmZSBleHBlY3RhbmN5IGFzIHBlciBLYXBsYW4gKGNydWRlKQpDQ1Nfc2luZ2xlCmBgYAoKYGBge3J9CiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoMjEpCm91dCA8LSBzc2EoCiAgeDAgPSB4MCwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXMsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikgCgoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YSA8LSBvdXQkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnNpbmdsZV9wbG90IDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoYWxwaGE9MC44KSsKICBsYWJzKHg9IlRpbWUgKERheXMpIiwKICAgICAgIHk9Ik51bWJlciBvZiBJbmRpdmlkdWFscyIsIAogICAgICAgY29sb3VyPSJTdGF0ZSIpKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IGV4cGV4dGVkX2luZmVjdGVkcywgbGluZXR5cGUgPSAnZGFzaGVkJykgKwogIHRoZW1lX2J3KCkKCnNpbmdsZV9wbG90CgpnZ3NhdmUoZmlsZW5hbWUgPSAic2luZ2xlX3Bsb3QucGRmIiwgCiAgICAgICBwbG90ID0gc2luZ2xlX3Bsb3QsCiAgICAgICBkZXZpY2UgPSAicGRmIiwKICAgICAgIHdpZHRoID0gNywgCiAgICAgICBoZWlnaHQgPSAzLAogICAgICAgcGF0aCA9ICIvVXNlcnMvbWF0dGhld2hveWxlL0dpdGh1Yl9SX3Byb2plY3RzL0h1bnRlcl9HYXRoZXJlcl9tb2RlbHMiKQpgYGAKCmBgYHtyfQpwbG90X2RhdGEgJT4lCiAgZmlsdGVyKHN0YXRlID09ICJJIikgJT4lCiAgc2xpY2VfbWF4KGNvdW50KQpgYGAKCgpgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3QgPC0gbGlzdCgpCnNpbV9saXN0IDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIAogIE4gPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDEpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MCA8LSBjKE4gLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOKQoKICBuYW1lcyh4MCkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBzZXQuc2VlZChpKQogIG91dF8xMDAgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXMsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YSA8LSBvdXRfMTAwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdFtbaV1dIDwtIHNpbV9kYXRhCn0KCnNpbV9vdXRwdXQgPC0gYmluZF9yb3dzKHNpbV9saXN0KQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0IDwtIHNpbV9vdXRwdXQgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0CgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnkgPC0gc2ltX291dHB1dCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAKICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEwMCkKc2ltX3N1bW1hcnkKYGBgCiMjIyBWYXJ5aW5nIHdhaW5pbmcgaW1tdW5pdHkKIyMjIyAwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMCA8LSBwYXJtcwpwYXJtc18wJG9tZWdhIDwtIDAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8wIDwtIHNzYSgKICB4MCA9IHgwLAogIGEgPSBhLAogIG51ID0gbnUsCiAgcGFybXMgPSBwYXJtc18wLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzAgPC0gb3V0XzAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8wLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8wIDwtIGxpc3QoKQpzaW1fbGlzdF8wIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTiA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwIDwtIGMoTiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE4pCgogIG5hbWVzKHgwKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMCA8LSBzc2EoCiAgICB4MCA9IHgwLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18wLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMCA8LSBvdXRfMTAwXzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzBbW2ldXSA8LSBzaW1fZGF0YV8wCn0KCnNpbV9vdXRwdXRfMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8wIDwtIHNpbV9vdXRwdXRfMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzAgPC0gc2ltX291dHB1dF8wICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDApCnNpbV9zdW1tYXJ5XzAKYGBgCgoKCgojIyMjIDEgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xIDwtIHBhcm1zCnBhcm1zXzEkb21lZ2EgPC0gMQoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzEgPC0gc3NhKAogIHgwID0geDAsCiAgYSA9IGEsCiAgbnUgPSBudSwKICBwYXJtcyA9IHBhcm1zXzEsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMSA8LSBvdXRfMSRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzEsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMQpgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzEgPC0gbGlzdCgpCnNpbV9saXN0XzEgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDAgPC0gYyhOIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTikKCiAgbmFtZXMoeDApIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8xIDwtIHNzYSgKICAgIHgwID0geDAsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzEsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xIDwtIG91dF8xMDBfMSRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMVtbaV1dIDwtIHNpbV9kYXRhXzEKfQoKc2ltX291dHB1dF8xIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzEgPC0gc2ltX291dHB1dF8xICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMSA8LSBzaW1fb3V0cHV0XzEgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMSkKc2ltX3N1bW1hcnlfMQpgYGAKCgoKCgojIyMjIDMgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zIDwtIHBhcm1zCnBhcm1zXzMkb21lZ2EgPC0gMS8zCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMyA8LSBzc2EoCiAgeDAgPSB4MCwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXNfMywKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zIDwtIG91dF8zJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzMgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMywgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMyA8LSBsaXN0KCkKc2ltX2xpc3RfMyA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE4gPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDEpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MCA8LSBjKE4gLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOKQoKICBuYW1lcyh4MCkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzMgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMywKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzMgPC0gb3V0XzEwMF8zJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zW1tpXV0gPC0gc2ltX2RhdGFfMwp9CgpzaW1fb3V0cHV0XzMgPC0gYmluZF9yb3dzKHNpbV9saXN0XzMpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMyA8LSBzaW1fb3V0cHV0XzMgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzMKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zIDwtIHNpbV9vdXRwdXRfMyAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzMpCnNpbV9zdW1tYXJ5XzMKYGBgCgojIyMjIDcgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc183IDwtIHBhcm1zCnBhcm1zXzckb21lZ2EgPC0gMS83CgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfNyA8LSBzc2EoCiAgeDAgPSB4MCwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXNfNywKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV83IDwtIG91dF83JGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzcgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfNywgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF83CmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfNyA8LSBsaXN0KCkKc2ltX2xpc3RfNyA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE4gPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDEpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MCA8LSBjKE4gLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOKQoKICBuYW1lcyh4MCkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzcgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfNywKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzcgPC0gb3V0XzEwMF83JGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF83W1tpXV0gPC0gc2ltX2RhdGFfNwp9CgpzaW1fb3V0cHV0XzcgPC0gYmluZF9yb3dzKHNpbV9saXN0XzcpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfNyA8LSBzaW1fb3V0cHV0XzcgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzcKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV83IDwtIHNpbV9vdXRwdXRfNyAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzcpCnNpbV9zdW1tYXJ5XzcKYGBgCgojIyMjIDEwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTAgPC0gcGFybXMKcGFybXNfMTAkb21lZ2EgPC0gMS8xMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzEwIDwtIHNzYSgKICB4MCA9IHgwLAogIGEgPSBhLAogIG51ID0gbnUsCiAgcGFybXMgPSBwYXJtc18xMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xMCA8LSBvdXRfMTAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMTAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xMCA8LSBsaXN0KCkKc2ltX2xpc3RfMTAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDAgPC0gYyhOIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTikKCiAgbmFtZXMoeDApIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8xMCA8LSBzc2EoCiAgICB4MCA9IHgwLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18xMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzEwIDwtIG91dF8xMDBfMTAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzEwW1tpXV0gPC0gc2ltX2RhdGFfMTAKfQoKc2ltX291dHB1dF8xMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTAgPC0gc2ltX291dHB1dF8xMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xMCA8LSBzaW1fb3V0cHV0XzEwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTApCnNpbV9zdW1tYXJ5XzEwCmBgYAoKIyMjIyAyMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzIwIDwtIHBhcm1zCnBhcm1zXzIwJG9tZWdhIDwtIDEvMjAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8yMCA8LSBzc2EoCiAgeDAgPSB4MCwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXNfMjAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMjAgPC0gb3V0XzIwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzIwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzIwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzIwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMjAgPC0gbGlzdCgpCnNpbV9saXN0XzIwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTiA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwIDwtIGMoTiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE4pCgogIG5hbWVzKHgwKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMjAgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMjAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8yMCA8LSBvdXRfMTAwXzIwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8yMFtbaV1dIDwtIHNpbV9kYXRhXzIwCn0KCnNpbV9vdXRwdXRfMjAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzIwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzIwIDwtIHNpbV9vdXRwdXRfMjAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzIwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMjAgPC0gc2ltX291dHB1dF8yMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzIwKQpzaW1fc3VtbWFyeV8yMApgYGAKCiMjIyMgMzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zMCA8LSBwYXJtcwpwYXJtc18zMCRvbWVnYSA8LSAxLzMwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMzAgPC0gc3NhKAogIHgwID0geDAsCiAgYSA9IGEsCiAgbnUgPSBudSwKICBwYXJtcyA9IHBhcm1zXzMwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzMwIDwtIG91dF8zMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8zMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzMwIDwtIGxpc3QoKQpzaW1fbGlzdF8zMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE4gPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDEpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MCA8LSBjKE4gLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOKQoKICBuYW1lcyh4MCkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzMwIDwtIHNzYSgKICAgIHgwID0geDAsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzMwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMzAgPC0gb3V0XzEwMF8zMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMzBbW2ldXSA8LSBzaW1fZGF0YV8zMAp9CgpzaW1fb3V0cHV0XzMwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zMCA8LSBzaW1fb3V0cHV0XzMwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzMwIDwtIHNpbV9vdXRwdXRfMzAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zMCkKc2ltX3N1bW1hcnlfMzAKYGBgCgojIyMjIDQwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfNDAgPC0gcGFybXMKcGFybXNfNDAkb21lZ2EgPC0gMS80MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzQwIDwtIHNzYSgKICB4MCA9IHgwLAogIGEgPSBhLAogIG51ID0gbnUsCiAgcGFybXMgPSBwYXJtc180MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV80MCA8LSBvdXRfNDAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfNDAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfNDAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfNDAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF80MCA8LSBsaXN0KCkKc2ltX2xpc3RfNDAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDAgPC0gYyhOIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTikKCiAgbmFtZXMoeDApIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF80MCA8LSBzc2EoCiAgICB4MCA9IHgwLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc180MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzQwIDwtIG91dF8xMDBfNDAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzQwW1tpXV0gPC0gc2ltX2RhdGFfNDAKfQoKc2ltX291dHB1dF80MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfNDApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfNDAgPC0gc2ltX291dHB1dF80MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfNDAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV80MCA8LSBzaW1fb3V0cHV0XzQwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNDApCnNpbV9zdW1tYXJ5XzQwCmBgYAoKIyMjIyA1MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzUwIDwtIHBhcm1zCnBhcm1zXzUwJG9tZWdhIDwtIDEvNTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF81MCA8LSBzc2EoCiAgeDAgPSB4MCwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXNfNTAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfNTAgPC0gb3V0XzUwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzUwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzUwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzUwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfNTAgPC0gbGlzdCgpCnNpbV9saXN0XzUwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTiA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwIDwtIGMoTiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE4pCgogIG5hbWVzKHgwKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfNTAgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfNTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV81MCA8LSBvdXRfMTAwXzUwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF81MFtbaV1dIDwtIHNpbV9kYXRhXzUwCn0KCnNpbV9vdXRwdXRfNTAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzUwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzUwIDwtIHNpbV9vdXRwdXRfNTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzUwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfNTAgPC0gc2ltX291dHB1dF81MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzUwKQpzaW1fc3VtbWFyeV81MApgYGAKCiMjIyMgNjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc182MCA8LSBwYXJtcwpwYXJtc182MCRvbWVnYSA8LSAxLzYwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfNjAgPC0gc3NhKAogIHgwID0geDAsCiAgYSA9IGEsCiAgbnUgPSBudSwKICBwYXJtcyA9IHBhcm1zXzYwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzYwIDwtIG91dF82MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF82MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV82MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF82MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzYwIDwtIGxpc3QoKQpzaW1fbGlzdF82MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE4gPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDEpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MCA8LSBjKE4gLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOKQoKICBuYW1lcyh4MCkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzYwIDwtIHNzYSgKICAgIHgwID0geDAsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzYwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfNjAgPC0gb3V0XzEwMF82MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfNjBbW2ldXSA8LSBzaW1fZGF0YV82MAp9CgpzaW1fb3V0cHV0XzYwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF82MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF82MCA8LSBzaW1fb3V0cHV0XzYwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF82MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzYwIDwtIHNpbV9vdXRwdXRfNjAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS82MCkKc2ltX3N1bW1hcnlfNjAKYGBgCgojIyMjIDcwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfNzAgPC0gcGFybXMKcGFybXNfNzAkb21lZ2EgPC0gMS83MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzcwIDwtIHNzYSgKICB4MCA9IHgwLAogIGEgPSBhLAogIG51ID0gbnUsCiAgcGFybXMgPSBwYXJtc183MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV83MCA8LSBvdXRfNzAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfNzAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfNzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfNzAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF83MCA8LSBsaXN0KCkKc2ltX2xpc3RfNzAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDAgPC0gYyhOIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTikKCiAgbmFtZXMoeDApIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF83MCA8LSBzc2EoCiAgICB4MCA9IHgwLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc183MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzcwIDwtIG91dF8xMDBfNzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzcwW1tpXV0gPC0gc2ltX2RhdGFfNzAKfQoKc2ltX291dHB1dF83MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfNzApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfNzAgPC0gc2ltX291dHB1dF83MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfNzAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV83MCA8LSBzaW1fb3V0cHV0XzcwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0KS9udW1fc2ltcykqMTAwLAogICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNzApCnNpbV9zdW1tYXJ5XzcwCmBgYAoKIyMjIyA4MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzgwIDwtIHBhcm1zCnBhcm1zXzgwJG9tZWdhIDwtIDEvODAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF84MCA8LSBzc2EoCiAgeDAgPSB4MCwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXNfODAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfODAgPC0gb3V0XzgwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzgwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzgwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzgwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfODAgPC0gbGlzdCgpCnNpbV9saXN0XzgwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTiA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwIDwtIGMoTiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE4pCgogIG5hbWVzKHgwKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfODAgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfODAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV84MCA8LSBvdXRfMTAwXzgwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF84MFtbaV1dIDwtIHNpbV9kYXRhXzgwCn0KCnNpbV9vdXRwdXRfODAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzgwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzgwIDwtIHNpbV9vdXRwdXRfODAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzgwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfODAgPC0gc2ltX291dHB1dF84MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzgwKQpzaW1fc3VtbWFyeV84MApgYGAKCiMjIyMgMTUwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTUwIDwtIHBhcm1zCnBhcm1zXzE1MCRvbWVnYSA8LSAxLzE1MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzE1MCA8LSBzc2EoCiAgeDAgPSB4MCwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXNfMTUwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE1MCA8LSBvdXRfMTUwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE1MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xNTAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMTUwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTUwIDwtIGxpc3QoKQpzaW1fbGlzdF8xNTAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDAgPC0gYyhOIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTikKCiAgbmFtZXMoeDApIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8xNTAgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMTUwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTUwIDwtIG91dF8xMDBfMTUwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNTBbW2ldXSA8LSBzaW1fZGF0YV8xNTAKfQoKc2ltX291dHB1dF8xNTAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE1MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNTAgPC0gc2ltX291dHB1dF8xNTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE1MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE1MCA8LSBzaW1fb3V0cHV0XzE1MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzE1MCkKc2ltX3N1bW1hcnlfMTUwCmBgYAoKIyMjIyAxODAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xODAgPC0gcGFybXMKcGFybXNfMTgwJG9tZWdhIDwtIDEvMTgwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTAwIDwtIHNzYSgKICB4MCA9IHgwLAogIGEgPSBhLAogIG51ID0gbnUsCiAgcGFybXMgPSBwYXJtc18xODAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTgwIDwtIG91dF8xODAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMTgwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE4MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xODAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xODAgPC0gbGlzdCgpCnNpbV9saXN0XzE4MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE4gPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDEpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MCA8LSBjKE4gLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOKQoKICBuYW1lcyh4MCkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzE4MCA8LSBzc2EoCiAgICB4MCA9IHgwLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18xODAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xODAgPC0gb3V0XzEwMF8xODAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE4MFtbaV1dIDwtIHNpbV9kYXRhXzE4MAp9CgpzaW1fb3V0cHV0XzE4MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTgwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE4MCA8LSBzaW1fb3V0cHV0XzE4MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTgwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTgwIDwtIHNpbV9vdXRwdXRfMTgwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTgwKQpzaW1fc3VtbWFyeV8xODAKYGBgCgoKIyMjIyAzNjUgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zNjUgPC0gcGFybXMKcGFybXNfMzY1JG9tZWdhIDwtIDEvMzY1CgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMzY1IDwtIHNzYSgKICB4MCA9IHgwLAogIGEgPSBhLAogIG51ID0gbnUsCiAgcGFybXMgPSBwYXJtc18zNjUsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMzY1IDwtIG91dF8zNjUkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMzY1IDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzM2NSwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zNjUKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zNjUgPC0gbGlzdCgpCnNpbV9saXN0XzM2NSA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE4gPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDEpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MCA8LSBjKE4gLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOKQoKICBuYW1lcyh4MCkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzM2NSA8LSBzc2EoCiAgICB4MCA9IHgwLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18zNjUsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zNjUgPC0gb3V0XzEwMF8zNjUkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzM2NVtbaV1dIDwtIHNpbV9kYXRhXzM2NQp9CgpzaW1fb3V0cHV0XzM2NSA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMzY1KQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzM2NSA8LSBzaW1fb3V0cHV0XzM2NSAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMzY1CgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMzY1IDwtIHNpbV9vdXRwdXRfMzY1ICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMzY1KQpzaW1fc3VtbWFyeV8zNjUKYGBgCgoKCiMjIyMgUmVzdWx0cwpgYGB7cn0Kd2FuaW5nX3Jlc3VsdHNfc2luZ2xlIDwtIHNpbV9zdW1tYXJ5ICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMykgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzcpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzIwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMzApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV80MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzUwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfNjApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV83MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzgwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTAwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTUwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMzY1KSAlPiUKICBtdXRhdGUoaW1tdW5pdHlfZHVyYXRpb24gPSAxL29tZWdhKSAlPiUKICBhcnJhbmdlKGltbXVuaXR5X2R1cmF0aW9uKSAlPiUKICBtdXRhdGUobW9kZWw9InNpbmdsZSIpCgp3cml0ZV9jc3Yod2FuaW5nX3Jlc3VsdHNfc2luZ2xlLCBmaWxlID0gIi9Vc2Vycy9tYXR0aGV3aG95bGUvR2l0aHViX1JfcHJvamVjdHMvSHVudGVyX0dhdGhlcmVyX21vZGVscy93YW5pbmdfcmVzdWx0c19zaW5nbGUuY3N2IikKCndhbmluZ19yZXN1bHRzX3NpbmdsZQoKYGBgCgpgYGB7cn0KZ2dwbG90KHdhbmluZ19yZXN1bHRzX3NpbmdsZSwgYWVzKGltbXVuaXR5X2R1cmF0aW9uLCBzdW1fcGVyc2lzdCkpICsKICBnZW9tX2xpbmUoKSsKICBnZW9tX3BvaW50KCkrCiAgdGhlbWVfYncoKQpgYGAKCgoKCiMjIE1ldGFwb3B1bGF0aW9uIE1vZGVsIAoKIyMjU2V0LXVwCgpgYGB7cn0KIyBEZWZpbmUgUGFyYW1lbnRlcnMKcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBQYXRjaCBzaXplClUgPC0gbGVuZ3RoKHBhdGNoUG9wU2l6ZSkgICAgICAgICAgICAgICAgICAgICMgTnVtYmVyIG9mIHBhdGNoZXMKaW5pdGlhbF9pbmZlY3RlZCA8LSAgYXMudmVjdG9yKHJtdWx0aW5vbSgxLCAxLCByZXAoMC41LCBVKSkpICAgIyBJbml0aWFsIGluZmVjdGVkIChpbml0aWFsIGluZmVjdGVkIHBhdGNoIHJhbmRvbWx5IGdlbmVyYXRlZCkKaW5pdGlhbF9pbmZlY3RlZF9wYXRjaCA8LSB3aGljaChpbml0aWFsX2luZmVjdGVkID4gMCkKc2ltTmFtZSA8LSAiU0lSUyBtZXRhcG9wdWxhdGlvbiBtb2RlbCIgICAgICAgIyBTaW11bGF0aW9uIG5hbWUKdGYgPC0gMzY1KjMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRmluYWwgdGltZQoKIyBBZ3RhIEh1bnRlci1HYXRoZXJlciBjb250YWN0IHJhdGVzCndpdGhpbl9wb3BfY29udGFjdCA9IDEKYmV0d2Vlbl9wb3BfY29udGFjdCA9IDAuNS9VICAgICAjIG5vcm1hbGlzZWQgYnkgbnVtYmVyIG9mIHBhdGNoZXMgCgojQ3JlYXRlIHRoZSBuYW1lZCBpbml0aWFsIHN0YXRlIHZlY3RvciBmb3IgdGhlIFUtcGF0Y2ggc3lzdGVtLgoKeDBfbWV0YSA8LSB1bmxpc3QobGFwcGx5KAogIHNlcV9sZW4oVSksIAogIGZ1bmN0aW9uKGkpeyAKICAgIGMocGF0Y2hQb3BTaXplW2ldIC0gaW5pdGlhbF9pbmZlY3RlZFtpXSwgaW5pdGlhbF9pbmZlY3RlZFtpXSwgMCwgMCwgcGF0Y2hQb3BTaXplW2ldKQogIH0KKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oaSkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgaSkpKQoKCiMgRGVmaW5lIHRoZSBzdGF0ZSBjaGFuZ2UgbWF0cml4IGZvciBhIHNpbmdsZSBwYXRjaApudV9tZXRhIDwtIG1hdHJpeChjKCAtMSwgIDAsICAwLCArMSwgKzEsIC0xLCAgMCwgIDAsICAwLCAgMCwgIyBTCiAgICAgICAgICAgICAgICAgICAgICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgIDAsICAwLCAjIEUKICAgICAgICAgICAgICAgICAgICAgIDAsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgLTEsICMgSQogICAgICAgICAgICAgICAgICAgICAgMCwgIDAsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgIyBSIAogICAgICAgICAgICAgICAgICAgICAgMCwgIDAsICAwLCAgMCwgKzEsIC0xICwtMSwgLTEsIC0xLCAtMSksICMgTgogICAgICAgICAgICAgbnJvdz01LGJ5cm93PVRSVUUpCgojIERlZmluZSBwcm9wZW5zaXR5IGZ1bmN0aW9ucwojIE1hc3MtYWN0aW9uCmFfbWV0YSA8LQogIHVubGlzdChsYXBwbHkoCiAgICBzZXFfbGVuKFUpLAogICAgZnVuY3Rpb24ocGF0Y2gpIHsKICAgICAgaSA8LSBwYXRjaAogICAgICBwYXRjaGVzIDwtIDE6VQogICAgICAjaiA8LSBpZiAocGF0Y2ggPT0gMSkgVSBlbHNlIHBhdGNoIC0gMQogICAgICBvdGhlcl9wYXRjaGVzIDwtIHBhdGNoZXNbLWldCiAgICAgIHBhdGNoX2JldGEgPC0gYygpCiAgICAgIGZvcihrIGluICgxOihVLTEpKSl7CiAgICAgICAgcGF0Y2hfYmV0YVtrXSA9IHBhc3RlMCgiKyhiZXRhXyIsIG90aGVyX3BhdGNoZXNba10saSwgIipJIiwgb3RoZXJfcGF0Y2hlc1trXSwgIi9OIiwgb3RoZXJfcGF0Y2hlc1trXSwgIikqUyIsIGkpCiAgICAgIH0KICAgICAgYygKICAgICAgICBwYXN0ZTAoIihiZXRhXyIsIGksIGksICIqSSIsIGksIi9OIiwgaSwgIikqUyIsaSwgcGFzdGUwKHBhdGNoX2JldGEsIGNvbGxhcHNlPSIiKSksICMgSW5mZWN0aW9uCiAgICAgICAgcGFzdGUwKCJzaWdtYSpFIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBCZWNvbWVzIGluZmVjaW91cwogICAgICAgIHBhc3RlMCgiZ2FtbWEqSSIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgUmVjb3ZlcnkgZnJvbSBpbmZlY3Rpb24KICAgICAgICBwYXN0ZTAoIm9tZWdhKlIiLCBpKSwgICAgICAgIyBMb3NzIG9mIGltbXVuaXR5CiAgICAgICAgcGFzdGUwKCJtdSpOIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEJpcnRocwogICAgICAgIHBhc3RlMCgibXUqUyIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIChTKQogICAgICAgIHBhc3RlMCgibXUqRSIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIChFKQogICAgICAgIHBhc3RlMCgibXUqSSIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIChJKQogICAgICAgIHBhc3RlMCgibXUqUiIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIChSKQogICAgICAgIHBhc3RlMCgiYWxwaGEqSSIsIGkpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIGZyb20gaW5mZWN0aW9uCiAgICAgICAgCiAgICAgICkKICAgIH0KICApKQoKYGBgCgpEZWZpbmUgZnVuY3Rpb25zIGZvciBjYWxjdWxhdGluZyBSMCBmcm9tIG5leHQtZ2VuZXJhdGlvbiBtYXRyaXgKYGBge3J9CiMgQ2FsY3VsYXRlIFIwIGZyb20gTkdNCgpSMG5nbSA8LSBmdW5jdGlvbihuZXh0Z2VuX21hdHJpeCkgewogIGVpZ2VudmFsdWVzID0gZWlnZW4obmV4dGdlbl9tYXRyaXgsIG9ubHkudmFsdWVzID0gVCkKICBSMCA9IG1heChhYnMoZWlnZW52YWx1ZXMkdmFsdWVzKSkKICByZXR1cm4oUjApCn0KCmJldGEubmdtIDwtIGZ1bmN0aW9uKGJldGFfbWF0cml4KSB7CiAgZWlnZW52YWx1ZXMgPSBlaWdlbihiZXRhX21hdHJpeCwgb25seS52YWx1ZXMgPSBUKQogIGJldGFfbmdtID0gbWF4KGFicyhlaWdlbnZhbHVlcyR2YWx1ZXMpKQogIHJldHVybihiZXRhX25nbSkKfQpgYGAKCgoKIyMjIE1ldGFwb3B1bGF0aW9uIE1vZGVsCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGEgPC0gbGlzdCgKICBzaWdtYSA9IDAuMTc1LCAgICAgICAgICAgICAgICAgICAgICAgICAgIyBFIHRvIEkgcmF0ZQogIGdhbW1hID0gMC4yLCAgICAgICAgICAgICAgICAgICAgICAgICAgICMgSSB0byBSIHJhdGUKICBvbWVnYSA9IDEvMTAwLCAgICAgICAgICAgICAgICAgICAgICAgICAjIFIgdG8gUyByYXRlCiAgbXUgPSBkZW1vX3N1bSRCaXJ0aF9yYXRlX2RhaWx5X01lYW4sICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQmlydGgvZGVhdGggcmF0ZSBwZXIgcGVyc29uIHBlciBkYXkKICBhbHBoYSA9IDEvMTAwMCkgCgojIERlZmluZSB0cmFuc21pc3Npb24gdGVybXMgYW5kIHBvcHVsYXRlIG5leHQtZ2VuZXJhdGlvbiBtYXRyaXgKYmV0YSA8LSAwLjYKCm5leHRnZW5fbWF0cml4IDwtIG1hdHJpeChucm93ID0gVSwgbmNvbCA9IFUsIGRhdGEgPSAwKQpiZXRhX21hdHJpeCA8LSBtYXRyaXgobnJvdyA9IFUsIG5jb2wgPSBVLCBkYXRhID0gMCkKCgpmb3IoaSBpbiAxOlUpewogIGZvcihqIGluIDE6VSl7CiAgICBwYXJtc19tZXRhW1twYXN0ZTAoImJldGFfIixpLGkpXV0gPSB3aXRoaW5fcG9wX2NvbnRhY3QqYmV0YQogICAgbmV4dGdlbl9tYXRyaXhbaSxpXSA9IHdpdGhpbl9wb3BfY29udGFjdCpiZXRhKigxL3Bhcm1zX21ldGEkZ2FtbWEpCiAgICBwYXJtc19tZXRhW1twYXN0ZTAoImJldGFfIixqLGkpXV0gPSBiZXR3ZWVuX3BvcF9jb250YWN0KmJldGEKICAgIG5leHRnZW5fbWF0cml4W2osaV0gPSBiZXR3ZWVuX3BvcF9jb250YWN0KmJldGEqKDEvcGFybXNfbWV0YSRnYW1tYSkKICAgIG5leHRnZW5fbWF0cml4W2ksal0gPSBiZXR3ZWVuX3BvcF9jb250YWN0KmJldGEqKDEvcGFybXNfbWV0YSRnYW1tYSkKICAgIHBhcm1zX21ldGFbW3Bhc3RlMCgiYmV0YV8iLGosaildXSA9IHdpdGhpbl9wb3BfY29udGFjdCpiZXRhCiAgICBuZXh0Z2VuX21hdHJpeFtqLGpdID0gd2l0aGluX3BvcF9jb250YWN0KmJldGEqKDEvcGFybXNfbWV0YSRnYW1tYSkKICAgIGJldGFfbWF0cml4W2ksaV0gPSB3aXRoaW5fcG9wX2NvbnRhY3QqYmV0YQogICAgYmV0YV9tYXRyaXhbaixpXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YQogICAgYmV0YV9tYXRyaXhbaSxqXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YQogICAgYmV0YV9tYXRyaXhbaixqXSA9IHdpdGhpbl9wb3BfY29udGFjdCpiZXRhCiAgfQogIHBhcm1zX21ldGFbW3Bhc3RlMCgiTiIsIGkpXV0gPSBwYXRjaFBvcFNpemVbaV0KfQpgYGAKCgpgYGB7cn0KIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCgyNSkKb3V0X21ldGEgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGEsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBQbG90CnBsb3RfZGF0YV9tZXRhIDwtIG91dF9tZXRhJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGEsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZShhbHBoYT0wLjgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAxLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIChEYXlzKSIsCiAgICAgICB5PSJOdW1iZXIgb2YgSW5kaXZpZHVhbHMiLAogICAgICAgY29sb3VyPSJTdGF0ZSIpKwogIHRoZW1lX2J3KCkKcGxvdF9tZXRhCgpnZ3NhdmUoZmlsZW5hbWUgPSAibWV0YV9wbG90LnBkZiIsIAogICAgICAgcGxvdCA9IHBsb3RfbWV0YSwKICAgICAgIGRldmljZSA9ICJwZGYiLAogICAgICAgd2lkdGggPSA3LCAKICAgICAgIGhlaWdodCA9IDgsCiAgICAgICBwYXRoID0gIi9Vc2Vycy9tYXR0aGV3aG95bGUvR2l0aHViX1JfcHJvamVjdHMvSHVudGVyX0dhdGhlcmVyX21vZGVscyIpCmBgYAoKYGBge3J9CiMjIFRhYmxlIHNob3dpbmcgZXh0aW5jdGlvbi90cmFuc21pc3Npb24gaW5mbyBmb3IgZWFjaCBwYXRjaAoKZXh0aW5jdF9kYXRhX21ldGEgPC0gb3V0X21ldGEkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBzbGljZV9tYXgodCkgJT4lCiAgZGlzdGluY3QoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHN0YXRlPT0iSSIgJiBjb3VudCA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZT09IkkiICYgY291bnQgPT0gMCB+IEYpKSAlPiUKICBkcm9wX25hKCkgJT4lCiAgc2VsZWN0KHBhdGNoLCBjb3VudCwgcGVyc2lzdCkKZXh0aW5jdF9kYXRhX21ldGEKYGBgCgoKYGBge3J9CmJldGFfbWV0YSA8LSBiZXRhLm5nbShiZXRhX21hdHJpeCkKcGFzdGUwKCJCZXRhIGZvciB3aG9sZSBzeXN0ZW0gPSAiLCBiZXRhX21ldGEpCgoKUjBfbWV0YSA8LSBSMG5nbShuZXh0Z2VuX21hdHJpeCkKcGFzdGUwKCJSMCA9ICIsIFIwX21ldGEpCgoKcGFzdGUwKCJBY3R1YWwgbnVtYmVyIG9mIGluZmVjdGVkcyBhdCBlbmQgb2Ygc2ltID0gIiwgc3VtKGV4dGluY3RfZGF0YV9tZXRhJGNvdW50KSkKICMgVG90YWwgbnVtYmVyIG9mIGluZmVjdGVkcyBhdCB0aGUgZW5kIG9mIHNpbSBhY3Jvc3MgYWxsIHBhdGNoZXMKCnNpbV9lbmRwb2ludF9tZXRhIDwtIGFzX3RpYmJsZShvdXRfbWV0YSRkYXRhKSAlPiUKICBzbGljZV9tYXgodCkgJT4lCiAgZGlzdGluY3QoKQoKCnBhc3RlMCgiRGlkIHNpbXVsYXRpb24gcnVuIHJlYWNoIGZpbmFsIGVuZHBvaW50PyIpCmlmIChzaW1fZW5kcG9pbnRfbWV0YSR0ID49IHRmKSB7CiAgcHJpbnQoIlllcyIpCn0gZWxzZSB7CiAgcHJpbnQoIk5vIil9CgpgYGAKCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KGxhcHBseSgKICBzZXFfbGVuKFUpLCAKICBmdW5jdGlvbih4KXsgCiAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICB9CikpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKICAKICBvdXRfMTAwX21ldGEgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YSwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGEgPC0gb3V0XzEwMF9tZXRhJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFbW2ldXSA8LSBzaW1fZGF0YV9tZXRhCn0KCnNpbV9vdXRwdXRfbWV0YSA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhIDwtIHNpbV9vdXRwdXRfbWV0YSAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YQpgYGAKCgoKYGBge3J9CiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhIDwtIHNpbV9vdXRwdXRfbWV0YSAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLAogICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTAwKQpzaW1fc3VtbWFyeV9tZXRhCmBgYAoKIyMjIFZhcnlpbmcgd2FpbmluZyBpbW11bml0eQojIyMjIDAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzAkb21lZ2EgPC0gMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfMCA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV8wLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfMCA8LSBvdXRfbWV0YV8wJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV8wLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV8wCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV8wIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfMCA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzAgPC0gb3V0XzEwMF9tZXRhXzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV8wW1tpXV0gPC0gc2ltX2RhdGFfbWV0YV8wCn0KCnNpbV9vdXRwdXRfbWV0YV8wIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV8wIDwtIHNpbV9vdXRwdXRfbWV0YV8wICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhXzAgPC0gc2ltX291dHB1dF9tZXRhXzAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwKICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAwKQpzaW1fc3VtbWFyeV9tZXRhXzAKYGBgCgoKCiMjIyMgMSBEYXkKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV8xIDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV8xJG9tZWdhIDwtIDEKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzEgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfMSwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzEgPC0gb3V0X21ldGFfMSRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV8xIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfMSwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfMQpgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfMSA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV8xIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzEgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV8xLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV8xIDwtIG91dF8xMDBfbWV0YV8xJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfMVtbaV1dIDwtIHNpbV9kYXRhX21ldGFfMQp9CgpzaW1fb3V0cHV0X21ldGFfMSA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV8xKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfMSA8LSBzaW1fb3V0cHV0X21ldGFfMSAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YV8xCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV8xIDwtIHNpbV9vdXRwdXRfbWV0YV8xICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEpCnNpbV9zdW1tYXJ5X21ldGFfMQpgYGAKCgoKCiMjIyMgMyBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfMyA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfMyRvbWVnYSA8LSAxLzMKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzMgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfMywKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzMgPC0gb3V0X21ldGFfMyRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV8zIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfMywgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfMwpgYGAKCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzMgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfMyA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfbWV0YV8zIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfMywKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfMyA8LSBvdXRfMTAwX21ldGFfMyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzNbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzMKfQoKc2ltX291dHB1dF9tZXRhXzMgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfMykKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzMgPC0gc2ltX291dHB1dF9tZXRhXzMgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfMwoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfMyA8LSBzaW1fb3V0cHV0X21ldGFfMyAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzMpCnNpbV9zdW1tYXJ5X21ldGFfMwpgYGAKCgoKCgoKIyMjIyA3IERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV83IDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV83JG9tZWdhIDwtIDEvNwoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfNyA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV83LAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfNyA8LSBvdXRfbWV0YV83JGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzcgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV83LCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV83CmBgYAoKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfNyA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV83IDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzcgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV83LAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV83IDwtIG91dF8xMDBfbWV0YV83JGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfN1tbaV1dIDwtIHNpbV9kYXRhX21ldGFfNwp9CgpzaW1fb3V0cHV0X21ldGFfNyA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV83KQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfNyA8LSBzaW1fb3V0cHV0X21ldGFfNyAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YV83CgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV83IDwtIHNpbV9vdXRwdXRfbWV0YV83ICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNykKc2ltX3N1bW1hcnlfbWV0YV83CmBgYAoKCgojIyMjIDEwIERheXMKCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfMTAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzEwJG9tZWdhIDwtIDEvMTAKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfMTAgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfMTAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV8xMCA8LSBvdXRfbWV0YV8xMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV8xMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzEwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV8xMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfMTAgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfMTAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfMTAgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV8xMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfMTAgPC0gb3V0XzEwMF9tZXRhXzEwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfMTBbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzEwCn0KCnNpbV9vdXRwdXRfbWV0YV8xMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV8xMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzEwIDwtIHNpbV9vdXRwdXRfbWV0YV8xMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV8xMCA8LSBzaW1fb3V0cHV0X21ldGFfMTAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xNCkKc2ltX3N1bW1hcnlfbWV0YV8xMApgYGAKCgojIyMjIDIwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV8yMCA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfMjAkb21lZ2EgPC0gMS8yMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfMjAgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfMjAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV8yMCA8LSBvdXRfbWV0YV8yMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV8yMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzIwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV8yMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfMjAgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfMjAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfMjAgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV8yMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfMjAgPC0gb3V0XzEwMF9tZXRhXzIwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfMjBbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzIwCn0KCnNpbV9vdXRwdXRfbWV0YV8yMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV8yMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzIwIDwtIHNpbV9vdXRwdXRfbWV0YV8yMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YV8yMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfMjAgPC0gc2ltX291dHB1dF9tZXRhXzIwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMjApCnNpbV9zdW1tYXJ5X21ldGFfMjAKYGBgCgoKCgoKCiMjIyMgMzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzMwIDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV8zMCRvbWVnYSA8LSAxLzMwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfbWV0YV8zMCA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV8zMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzMwIDwtIG91dF9tZXRhXzMwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzMwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfMzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF9tZXRhXzMwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV8zMCA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV8zMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfbWV0YV8zMCA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzMwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV8zMCA8LSBvdXRfMTAwX21ldGFfMzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV8zMFtbaV1dIDwtIHNpbV9kYXRhX21ldGFfMzAKfQoKc2ltX291dHB1dF9tZXRhXzMwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzMwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfMzAgPC0gc2ltX291dHB1dF9tZXRhXzMwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzMwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV8zMCA8LSBzaW1fb3V0cHV0X21ldGFfMzAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwKICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzMwKQpzaW1fc3VtbWFyeV9tZXRhXzMwCmBgYAoKCgojIyMjIDQwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV80MCA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfNDAkb21lZ2EgPC0gMS80MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfNDAgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfNDAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV80MCA8LSBvdXRfbWV0YV80MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV80MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzQwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV80MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfNDAgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfNDAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfNDAgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV80MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfNDAgPC0gb3V0XzEwMF9tZXRhXzQwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfNDBbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzQwCn0KCnNpbV9vdXRwdXRfbWV0YV80MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV80MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzQwIDwtIHNpbV9vdXRwdXRfbWV0YV80MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YV80MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfNDAgPC0gc2ltX291dHB1dF9tZXRhXzQwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNDApCnNpbV9zdW1tYXJ5X21ldGFfNDAKYGBgCgoKCgoKCgojIyMjIDUwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV81MCA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfNTAkb21lZ2EgPC0gMS81MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfNTAgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfNTAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV81MCA8LSBvdXRfbWV0YV81MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV81MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzUwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV81MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfNTAgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfNTAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfNTAgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV81MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfNTAgPC0gb3V0XzEwMF9tZXRhXzUwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfNTBbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzUwCn0KCnNpbV9vdXRwdXRfbWV0YV81MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV81MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzUwIDwtIHNpbV9vdXRwdXRfbWV0YV81MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YV81MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfNTAgPC0gc2ltX291dHB1dF9tZXRhXzUwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNTApCnNpbV9zdW1tYXJ5X21ldGFfNTAKYGBgCgoKCgoKIyMjIyA2MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfNjAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzYwJG9tZWdhIDwtIDEvNjAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzYwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzYwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfNjAgPC0gb3V0X21ldGFfNjAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfNjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV82MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfNjAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzYwIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzYwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzYwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfNjAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzYwIDwtIG91dF8xMDBfbWV0YV82MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzYwW1tpXV0gPC0gc2ltX2RhdGFfbWV0YV82MAp9CgpzaW1fb3V0cHV0X21ldGFfNjAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfNjApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV82MCA8LSBzaW1fb3V0cHV0X21ldGFfNjAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfNjAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhXzYwIDwtIHNpbV9vdXRwdXRfbWV0YV82MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzYwKQpzaW1fc3VtbWFyeV9tZXRhXzYwCmBgYAoKCgoKIyMjIyA3MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfNzAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzcwJG9tZWdhIDwtIDEvNzAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzcwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzcwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfNzAgPC0gb3V0X21ldGFfNzAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfNzAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV83MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfNzAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzcwIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzcwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzcwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfNzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzcwIDwtIG91dF8xMDBfbWV0YV83MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzcwW1tpXV0gPC0gc2ltX2RhdGFfbWV0YV83MAp9CgpzaW1fb3V0cHV0X21ldGFfNzAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfNzApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV83MCA8LSBzaW1fb3V0cHV0X21ldGFfNzAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfNzAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhXzcwIDwtIHNpbV9vdXRwdXRfbWV0YV83MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzcwKQpzaW1fc3VtbWFyeV9tZXRhXzcwCmBgYAoKCiMjIyMgODAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzgwIDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV84MCRvbWVnYSA8LSAxLzgwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfbWV0YV84MCA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV84MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzgwIDwtIG91dF9tZXRhXzgwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzgwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfODAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF9tZXRhXzgwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV84MCA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV84MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfbWV0YV84MCA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzgwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV84MCA8LSBvdXRfMTAwX21ldGFfODAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV84MFtbaV1dIDwtIHNpbV9kYXRhX21ldGFfODAKfQoKc2ltX291dHB1dF9tZXRhXzgwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzgwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfODAgPC0gc2ltX291dHB1dF9tZXRhXzgwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzgwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV84MCA8LSBzaW1fb3V0cHV0X21ldGFfODAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS84MCkKc2ltX3N1bW1hcnlfbWV0YV84MApgYGAKCgoKIyMjIyA5MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfOTAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzkwJG9tZWdhIDwtIDEvOTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzkwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzkwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfOTAgPC0gb3V0X21ldGFfOTAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfOTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV85MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfOTAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzkwIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzkwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzkwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfOTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzkwIDwtIG91dF8xMDBfbWV0YV85MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzkwW1tpXV0gPC0gc2ltX2RhdGFfbWV0YV85MAp9CgpzaW1fb3V0cHV0X21ldGFfOTAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfOTApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV85MCA8LSBzaW1fb3V0cHV0X21ldGFfOTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfOTAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhXzkwIDwtIHNpbV9vdXRwdXRfbWV0YV85MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzkwKQpzaW1fc3VtbWFyeV9tZXRhXzkwCmBgYAoKCgoKCgoKIyMjIyAxODAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzE4MCA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfMTgwJG9tZWdhIDwtIDEvMTgwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCgyMCkKb3V0X21ldGFfMTgwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzE4MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzE4MCA8LSBvdXRfbWV0YV8xODAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfMTgwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfMTgwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV8xODAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzE4MCA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV8xODAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfMTgwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfMTgwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV8xODAgPC0gb3V0XzEwMF9tZXRhXzE4MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzE4MFtbaV1dIDwtIHNpbV9kYXRhX21ldGFfMTgwCn0KCnNpbV9vdXRwdXRfbWV0YV8xODAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfMTgwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfMTgwIDwtIHNpbV9vdXRwdXRfbWV0YV8xODAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfMTgwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV8xODAgPC0gc2ltX291dHB1dF9tZXRhXzE4MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzE4MCkKc2ltX3N1bW1hcnlfbWV0YV8xODAKYGBgCgojIyMjIDExMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfMTEwIDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV8xMTAkb21lZ2EgPC0gMS8xMTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzExMCA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV8xMTAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV8xMTAgPC0gb3V0X21ldGFfMTEwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzExMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzExMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfMTEwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV8xMTAgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfMTEwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzExMCA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzExMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfMTEwIDwtIG91dF8xMDBfbWV0YV8xMTAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV8xMTBbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzExMAp9CgpzaW1fb3V0cHV0X21ldGFfMTEwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzExMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzExMCA8LSBzaW1fb3V0cHV0X21ldGFfMTEwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzExMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfMTEwIDwtIHNpbV9vdXRwdXRfbWV0YV8xMTAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMTApCnNpbV9zdW1tYXJ5X21ldGFfMTEwCmBgYAoKIyMjIyAxMjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzEyMCA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfMTIwJG9tZWdhIDwtIDEvMTIwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfbWV0YV8xMjAgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfMTIwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfMTIwIDwtIG91dF9tZXRhXzEyMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV8xMjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV8xMjAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF9tZXRhXzEyMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfMTIwIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzEyMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfbWV0YV8xMjAgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV8xMjAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzEyMCA8LSBvdXRfMTAwX21ldGFfMTIwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfMTIwW1tpXV0gPC0gc2ltX2RhdGFfbWV0YV8xMjAKfQoKc2ltX291dHB1dF9tZXRhXzEyMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV8xMjApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV8xMjAgPC0gc2ltX291dHB1dF9tZXRhXzEyMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YV8xMjAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhXzEyMCA8LSBzaW1fb3V0cHV0X21ldGFfMTIwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTIwKQpzaW1fc3VtbWFyeV9tZXRhXzEyMApgYGAKCiMjIyMgMTMwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV8xMzAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzEzMCRvbWVnYSA8LSAxLzEzMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfMTMwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzEzMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzEzMCA8LSBvdXRfbWV0YV8xMzAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfMTMwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfMTMwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV8xMzAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzEzMCA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV8xMzAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfMTMwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfMTMwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV8xMzAgPC0gb3V0XzEwMF9tZXRhXzEzMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzEzMFtbaV1dIDwtIHNpbV9kYXRhX21ldGFfMTMwCn0KCnNpbV9vdXRwdXRfbWV0YV8xMzAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfMTMwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfMTMwIDwtIHNpbV9vdXRwdXRfbWV0YV8xMzAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfMTMwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV8xMzAgPC0gc2ltX291dHB1dF9tZXRhXzEzMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEzMCkKc2ltX3N1bW1hcnlfbWV0YV8xMzAKYGBgCgoKCgoKCgoKCgoKCiMjIyMgMTUwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV8xNTAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzE1MCRvbWVnYSA8LSAxLzE1MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfMTUwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzE1MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzE1MCA8LSBvdXRfbWV0YV8xNTAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfMTUwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfMTUwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV8xNTAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzE1MCA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV8xNTAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfMTUwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfMTUwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV8xNTAgPC0gb3V0XzEwMF9tZXRhXzE1MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzE1MFtbaV1dIDwtIHNpbV9kYXRhX21ldGFfMTUwCn0KCnNpbV9vdXRwdXRfbWV0YV8xNTAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfMTUwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfMTUwIDwtIHNpbV9vdXRwdXRfbWV0YV8xNTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfMTUwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV8xNTAgPC0gc2ltX291dHB1dF9tZXRhXzE1MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzE1MCkKc2ltX3N1bW1hcnlfbWV0YV8xNTAKYGBgCgoKIyMjIyAyMjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzIyMCA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfMjIwJG9tZWdhIDwtIDEvMjIwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfbWV0YV8yMjAgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfMjIwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfMjIwIDwtIG91dF9tZXRhXzIyMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV8yMjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV8yMjAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF9tZXRhXzIyMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfMjIwIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzIyMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfbWV0YV8yMjAgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV8yMjAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzIyMCA8LSBvdXRfMTAwX21ldGFfMjIwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfMjIwW1tpXV0gPC0gc2ltX2RhdGFfbWV0YV8yMjAKfQoKc2ltX291dHB1dF9tZXRhXzIyMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV8yMjApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV8yMjAgPC0gc2ltX291dHB1dF9tZXRhXzIyMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YV8yMjAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhXzIyMCA8LSBzaW1fb3V0cHV0X21ldGFfMjIwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMjIwKQpzaW1fc3VtbWFyeV9tZXRhXzIyMApgYGAKCgoKCiMjIyMgMjcwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV8yNzAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzI3MCRvbWVnYSA8LSAxLzI3MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfMjcwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzI3MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzI3MCA8LSBvdXRfbWV0YV8yNzAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfMjcwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfMjcwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV8yNzAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzI3MCA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV8yNzAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfMjcwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfMjcwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV8yNzAgPC0gb3V0XzEwMF9tZXRhXzI3MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzI3MFtbaV1dIDwtIHNpbV9kYXRhX21ldGFfMjcwCn0KCnNpbV9vdXRwdXRfbWV0YV8yNzAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfMjcwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfMjcwIDwtIHNpbV9vdXRwdXRfbWV0YV8yNzAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfMjcwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV8yNzAgPC0gc2ltX291dHB1dF9tZXRhXzI3MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzI3MCkKc2ltX3N1bW1hcnlfbWV0YV8yNzAKYGBgCgojIyMjIDM2NSBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfMzY1IDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV8zNjUkb21lZ2EgPC0gMS8zNjUKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzM2NSA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV8zNjUsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV8zNjUgPC0gb3V0X21ldGFfMzY1JGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzM2NSA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzM2NSwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfMzY1CmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV8zNjUgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfMzY1IDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzM2NSA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzM2NSwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfMzY1IDwtIG91dF8xMDBfbWV0YV8zNjUkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV8zNjVbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzM2NQp9CgpzaW1fb3V0cHV0X21ldGFfMzY1IDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzM2NSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzM2NSA8LSBzaW1fb3V0cHV0X21ldGFfMzY1ICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzM2NQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfMzY1IDwtIHNpbV9vdXRwdXRfbWV0YV8zNjUgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zNjUpCnNpbV9zdW1tYXJ5X21ldGFfMzY1CmBgYAoKU2luZ2xlCgoKCgoKIyMjIyBSZXN1bHRzCmBgYHtyfQp3YW5pbmdfcmVzdWx0cyA8LSBzaW1fc3VtbWFyeV9tZXRhICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzMpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzcpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzEwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfbWV0YV8yMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfMzApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzQwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfbWV0YV81MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfNjApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzcwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfbWV0YV84MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfOTApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzEwMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfMTEwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfbWV0YV8xMjApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzEzMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfMTUwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfbWV0YV8yMjApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzI3MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfMzY1KSAlPiUKICBtdXRhdGUoaW1tdW5pdHlfZHVyYXRpb24gPSAxL29tZWdhKSAlPiUKICBhcnJhbmdlKGltbXVuaXR5X2R1cmF0aW9uKSAlPiUKICBtdXRhdGUobW9kZWwgPSAibWV0YSIpCgp3cml0ZV9jc3Yod2FuaW5nX3Jlc3VsdHMsIGZpbGUgPSAiL1VzZXJzL21hdHRoZXdob3lsZS9HaXRodWJfUl9wcm9qZWN0cy9IdW50ZXJfR2F0aGVyZXJfbW9kZWxzL3dhbmluZ19yZXN1bHRzLmNzdiIpCgp3YW5pbmdfcmVzdWx0cwoKYGBgCgpgYGB7cn0KZ2dwbG90KHdhbmluZ19yZXN1bHRzLCBhZXMoaW1tdW5pdHlfZHVyYXRpb24sIHN1bV9wZXJzaXN0KSkgKwogIGdlb21fbGluZSgpKwogIGdlb21fcG9pbnQoKSsKICB0aGVtZV9idygpCmBgYAoKCgoKIyMgMyBNZXRhcG9wdWxhdGlvbiBNb2RlbCAKCiMjI1NldC11cAoKYGBge3J9CiMgRGVmaW5lIFBhcmFtZW50ZXJzCnBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBQYXRjaCBzaXplClUgPC0gbGVuZ3RoKHBhdGNoUG9wU2l6ZV8zKSAgICAgICAgICAgICAgICAgICAgIyBOdW1iZXIgb2YgcGF0Y2hlcwppbml0aWFsX2luZmVjdGVkIDwtICBhcy52ZWN0b3Iocm11bHRpbm9tKDEsIDEsIHJlcCgwLjUsIFUpKSkgICAjIEluaXRpYWwgaW5mZWN0ZWQgKGluaXRpYWwgaW5mZWN0ZWQgcGF0Y2ggcmFuZG9tbHkgZ2VuZXJhdGVkKQppbml0aWFsX2luZmVjdGVkX3BhdGNoIDwtIHdoaWNoKGluaXRpYWxfaW5mZWN0ZWQgPiAwKQpzaW1OYW1lIDwtICJTSVJTIG1ldGFwb3B1bGF0aW9uIG1vZGVsIiAgICAgICAjIFNpbXVsYXRpb24gbmFtZQp0ZiA8LSAzNjUqMyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBGaW5hbCB0aW1lCgojIEFndGEgSHVudGVyLUdhdGhlcmVyIGNvbnRhY3QgcmF0ZXMKd2l0aGluX3BvcF9jb250YWN0ID0gMQpiZXR3ZWVuX3BvcF9jb250YWN0ID0gMC41L1UgICAgICMgbm9ybWFsaXNlZCBieSBudW1iZXIgb2YgcGF0Y2hlcyAKCiNDcmVhdGUgdGhlIG5hbWVkIGluaXRpYWwgc3RhdGUgdmVjdG9yIGZvciB0aGUgVS1wYXRjaCBzeXN0ZW0uCgp4MF8zX21ldGEgPC0gdW5saXN0KGxhcHBseSgKICBzZXFfbGVuKFUpLCAKICBmdW5jdGlvbihpKXsgCiAgICBjKHBhdGNoUG9wU2l6ZV8zW2ldIC0gaW5pdGlhbF9pbmZlY3RlZFtpXSwgaW5pdGlhbF9pbmZlY3RlZFtpXSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbaV0pCiAgfQopKQoKbmFtZXMoeDBfM19tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKGkpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIGkpKSkKCgojIERlZmluZSB0aGUgc3RhdGUgY2hhbmdlIG1hdHJpeCBmb3IgYSBzaW5nbGUgcGF0Y2gKbnVfM19tZXRhIDwtIG1hdHJpeChjKCAtMSwgIDAsICAwLCArMSwgKzEsIC0xLCAgMCwgIDAsICAwLCAgMCwgIyBTCiAgICAgICAgICAgICAgICAgICAgICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgIDAsICAwLCAjIEUKICAgICAgICAgICAgICAgICAgICAgIDAsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgLTEsICMgSQogICAgICAgICAgICAgICAgICAgICAgMCwgIDAsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgIyBSIAogICAgICAgICAgICAgICAgICAgICAgMCwgIDAsICAwLCAgMCwgKzEsIC0xICwtMSwgLTEsIC0xLCAtMSksICMgTgogICAgICAgICAgICAgbnJvdz01LGJ5cm93PVRSVUUpCgojIERlZmluZSBwcm9wZW5zaXR5IGZ1bmN0aW9ucwojIE1hc3MtYWN0aW9uCmFfM19tZXRhIDwtCiAgdW5saXN0KGxhcHBseSgKICAgIHNlcV9sZW4oVSksCiAgICBmdW5jdGlvbihwYXRjaCkgewogICAgICBpIDwtIHBhdGNoCiAgICAgIHBhdGNoZXMgPC0gMTpVCiAgICAgICNqIDwtIGlmIChwYXRjaCA9PSAxKSBVIGVsc2UgcGF0Y2ggLSAxCiAgICAgIG90aGVyX3BhdGNoZXMgPC0gcGF0Y2hlc1staV0KICAgICAgcGF0Y2hfYmV0YSA8LSBjKCkKICAgICAgZm9yKGsgaW4gKDE6KFUtMSkpKXsKICAgICAgICBwYXRjaF9iZXRhW2tdID0gcGFzdGUwKCIrKGJldGFfIiwgb3RoZXJfcGF0Y2hlc1trXSxpLCAiKkkiLCBvdGhlcl9wYXRjaGVzW2tdLCAiL04iLCBvdGhlcl9wYXRjaGVzW2tdLCAiKSpTIiwgaSkKICAgICAgfQogICAgICBjKAogICAgICAgIHBhc3RlMCgiKGJldGFfIiwgaSwgaSwgIipJIiwgaSwiL04iLCBpLCAiKSpTIixpLCBwYXN0ZTAocGF0Y2hfYmV0YSwgY29sbGFwc2U9IiIpKSwgIyBJbmZlY3Rpb24KICAgICAgICBwYXN0ZTAoInNpZ21hKkUiLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEJlY29tZXMgaW5mZWNpb3VzCiAgICAgICAgcGFzdGUwKCJnYW1tYSpJIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBSZWNvdmVyeSBmcm9tIGluZmVjdGlvbgogICAgICAgIHBhc3RlMCgib21lZ2EqUiIsIGkpLCAgICAgICAjIExvc3Mgb2YgaW1tdW5pdHkKICAgICAgICBwYXN0ZTAoIm11Kk4iLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQmlydGhzCiAgICAgICAgcGFzdGUwKCJtdSpTIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKFMpCiAgICAgICAgcGFzdGUwKCJtdSpFIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKEUpCiAgICAgICAgcGFzdGUwKCJtdSpJIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKEkpCiAgICAgICAgcGFzdGUwKCJtdSpSIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKFIpCiAgICAgICAgcGFzdGUwKCJhbHBoYSpJIiwgaSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgZnJvbSBpbmZlY3Rpb24KICAgICAgICAKICAgICAgKQogICAgfQogICkpCgpgYGAKCgoKIyMjIE1ldGFwb3B1bGF0aW9uIE1vZGVsCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YSA8LSBsaXN0KAogIHNpZ21hID0gMC4xNzUsICAgICAgICAgICAgICAgICAgICAgICAgICAjIEUgdG8gSSByYXRlCiAgZ2FtbWEgPSAwLjIsICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBJIHRvIFIgcmF0ZQogIG9tZWdhID0gMS8xMDAsICAgICAgICAgICAgICAgICAgICAgICAgICMgUiB0byBTIHJhdGUKICBtdSA9IGRlbW9fc3VtJEJpcnRoX3JhdGVfZGFpbHlfTWVhbiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBCaXJ0aC9kZWF0aCByYXRlIHBlciBwZXJzb24gcGVyIGRheQogIGFscGhhID0gMS8xMDAwKSAKCiMgRGVmaW5lIHRyYW5zbWlzc2lvbiB0ZXJtcyBhbmQgcG9wdWxhdGUgbmV4dC1nZW5lcmF0aW9uIG1hdHJpeApiZXRhIDwtIDAuNgoKbmV4dGdlbl8zX21hdHJpeCA8LSBtYXRyaXgobnJvdyA9IFUsIG5jb2wgPSBVLCBkYXRhID0gMCkKYmV0YV8zX21hdHJpeCA8LSBtYXRyaXgobnJvdyA9IFUsIG5jb2wgPSBVLCBkYXRhID0gMCkKCgpmb3IoaSBpbiAxOlUpewogIGZvcihqIGluIDE6VSl7CiAgICBwYXJtc18zX21ldGFbW3Bhc3RlMCgiYmV0YV8iLGksaSldXSA9IHdpdGhpbl9wb3BfY29udGFjdCpiZXRhCiAgICBuZXh0Z2VuXzNfbWF0cml4W2ksaV0gPSB3aXRoaW5fcG9wX2NvbnRhY3QqYmV0YSooMS9wYXJtc18zX21ldGEkZ2FtbWEpCiAgICBwYXJtc18zX21ldGFbW3Bhc3RlMCgiYmV0YV8iLGosaSldXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YQogICAgbmV4dGdlbl8zX21hdHJpeFtqLGldID0gYmV0d2Vlbl9wb3BfY29udGFjdCpiZXRhKigxL3Bhcm1zXzNfbWV0YSRnYW1tYSkKICAgIG5leHRnZW5fM19tYXRyaXhbaSxqXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YSooMS9wYXJtc18zX21ldGEkZ2FtbWEpCiAgICBwYXJtc18zX21ldGFbW3Bhc3RlMCgiYmV0YV8iLGosaildXSA9IHdpdGhpbl9wb3BfY29udGFjdCpiZXRhCiAgICBuZXh0Z2VuXzNfbWF0cml4W2osal0gPSB3aXRoaW5fcG9wX2NvbnRhY3QqYmV0YSooMS9wYXJtc18zX21ldGEkZ2FtbWEpCiAgICBiZXRhXzNfbWF0cml4W2ksaV0gPSB3aXRoaW5fcG9wX2NvbnRhY3QqYmV0YQogICAgYmV0YV8zX21hdHJpeFtqLGldID0gYmV0d2Vlbl9wb3BfY29udGFjdCpiZXRhCiAgICBiZXRhXzNfbWF0cml4W2ksal0gPSBiZXR3ZWVuX3BvcF9jb250YWN0KmJldGEKICAgIGJldGFfM19tYXRyaXhbaixqXSA9IHdpdGhpbl9wb3BfY29udGFjdCpiZXRhCiAgfQogIHBhcm1zXzNfbWV0YVtbcGFzdGUwKCJOIiwgaSldXSA9IHBhdGNoUG9wU2l6ZV8zW2ldCn0KYGBgCgoKYGBge3J9CiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoMjUpCm91dF8zX21ldGEgPC0gc3NhKAogIHgwID0geDBfM19tZXRhLAogIGEgPSBhXzNfbWV0YSwKICBudSA9IG51XzNfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzNfbWV0YSwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIFBsb3QKcGxvdF9kYXRhXzNfbWV0YSA8LSBvdXRfM19tZXRhJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGEgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoYWxwaGE9MC44KSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMSwgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSAoRGF5cykiLAogICAgICAgeT0iTnVtYmVyIG9mIEluZGl2aWR1YWxzIiwKICAgICAgIGNvbG91cj0iU3RhdGUiKSsKICB0aGVtZV9idygpCnBsb3RfM19tZXRhCgpnZ3NhdmUoZmlsZW5hbWUgPSAibWV0YV9wbG90LnBkZiIsIAogICAgICAgcGxvdCA9IHBsb3RfM19tZXRhLAogICAgICAgZGV2aWNlID0gInBkZiIsCiAgICAgICB3aWR0aCA9IDcsIAogICAgICAgaGVpZ2h0ID0gOCwKICAgICAgIHBhdGggPSAiL1VzZXJzL21hdHRoZXdob3lsZS9HaXRodWJfUl9wcm9qZWN0cy9IdW50ZXJfR2F0aGVyZXJfbW9kZWxzIikKYGBgCgpgYGB7cn0KIyMgVGFibGUgc2hvd2luZyBleHRpbmN0aW9uL3RyYW5zbWlzc2lvbiBpbmZvIGZvciBlYWNoIHBhdGNoCgpleHRpbmN0X2RhdGFfM19tZXRhIDwtIG91dF8zX21ldGEkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBzbGljZV9tYXgodCkgJT4lCiAgZGlzdGluY3QoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHN0YXRlPT0iSSIgJiBjb3VudCA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZT09IkkiICYgY291bnQgPT0gMCB+IEYpKSAlPiUKICBkcm9wX25hKCkgJT4lCiAgc2VsZWN0KHBhdGNoLCBjb3VudCwgcGVyc2lzdCkKZXh0aW5jdF9kYXRhXzNfbWV0YQpgYGAKCgpgYGB7cn0KYmV0YV8zX21ldGEgPC0gYmV0YS5uZ20oYmV0YV8zX21hdHJpeCkKcGFzdGUwKCJCZXRhIGZvciB3aG9sZSBzeXN0ZW0gPSAiLCBiZXRhXzNfbWV0YSkKCgpSMF8zX21ldGEgPC0gUjBuZ20obmV4dGdlbl8zX21hdHJpeCkKcGFzdGUwKCJSMCA9ICIsIFIwXzNfbWV0YSkKCgpwYXN0ZTAoIkFjdHVhbCBudW1iZXIgb2YgaW5mZWN0ZWRzIGF0IGVuZCBvZiBzaW0gPSAiLCBzdW0oZXh0aW5jdF9kYXRhXzNfbWV0YSRjb3VudCkpCiAjIFRvdGFsIG51bWJlciBvZiBpbmZlY3RlZHMgYXQgdGhlIGVuZCBvZiBzaW0gYWNyb3NzIGFsbCBwYXRjaGVzCgpzaW1fZW5kcG9pbnRfM19tZXRhIDwtIGFzX3RpYmJsZShvdXRfM19tZXRhJGRhdGEpICU+JQogIHNsaWNlX21heCh0KSAlPiUKICBkaXN0aW5jdCgpCgoKcGFzdGUwKCJEaWQgc2ltdWxhdGlvbiBydW4gcmVhY2ggZmluYWwgZW5kcG9pbnQ/IikKaWYgKHNpbV9lbmRwb2ludF8zX21ldGEkdCA+PSB0ZikgewogIHByaW50KCJZZXMiKQp9IGVsc2UgewogIHByaW50KCJObyIpfQoKYGBgCgpgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGEgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8zX21ldGEgPC0gdW5saXN0KGxhcHBseSgKICBzZXFfbGVuKFUpLCAKICBmdW5jdGlvbih4KXsgCiAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgfQopKQoKbmFtZXMoeDBfM19tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKICAKICBvdXRfMTAwXzNfbWV0YSA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGEsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zX21ldGEgPC0gb3V0XzEwMF8zX21ldGEkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhW1tpXV0gPC0gc2ltX2RhdGFfM19tZXRhCn0KCnNpbV9vdXRwdXRfM19tZXRhIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGEpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfM19tZXRhIDwtIHNpbV9vdXRwdXRfM19tZXRhICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGEKYGBgCgoKCmBgYHtyfQojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhIDwtIHNpbV9vdXRwdXRfM19tZXRhICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsCiAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMDApCnNpbV9zdW1tYXJ5XzNfbWV0YQpgYGAKCiMjIyBWYXJ5aW5nIHdhaW5pbmcgaW1tdW5pdHkKIyMjIyAwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfM19tZXRhXzAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8wJG9tZWdhIDwtIDAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfM19tZXRhXzAgPC0gb3V0XzNfbWV0YV8wJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8zX21ldGFfMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8wCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzAgPC0gbGlzdCgpCnNpbV9saXN0XzNfbWV0YV8wIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zX21ldGFfMCA8LSBvdXRfMTAwXzNfbWV0YV8wJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV8wW1tpXV0gPC0gc2ltX2RhdGFfM19tZXRhXzAKfQoKc2ltX291dHB1dF8zX21ldGFfMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfM19tZXRhXzAgPC0gc2ltX291dHB1dF8zX21ldGFfMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zX21ldGFfMCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8wICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsCiAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMCkKc2ltX3N1bW1hcnlfM19tZXRhXzAKYGBgCgoKCiMjIyMgMSBEYXkKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfM19tZXRhXzEgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8xJG9tZWdhIDwtIDEKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMSA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzEsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfM19tZXRhXzEgPC0gb3V0XzNfbWV0YV8xJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfMSA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8zX21ldGFfMSwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8xCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzEgPC0gbGlzdCgpCnNpbV9saXN0XzNfbWV0YV8xIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzEgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzEsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zX21ldGFfMSA8LSBvdXRfMTAwXzNfbWV0YV8xJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV8xW1tpXV0gPC0gc2ltX2RhdGFfM19tZXRhXzEKfQoKc2ltX291dHB1dF8zX21ldGFfMSA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzEpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfM19tZXRhXzEgPC0gc2ltX291dHB1dF8zX21ldGFfMSAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzEKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zX21ldGFfMSA8LSBzaW1fb3V0cHV0XzNfbWV0YV8xICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEpCnNpbV9zdW1tYXJ5XzNfbWV0YV8xCmBgYAoKCgoKIyMjIyAzIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfM19tZXRhXzMgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8zJG9tZWdhIDwtIDEvMwoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzNfbWV0YV8zIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfMywKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfMyA8LSBvdXRfM19tZXRhXzMkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV8zIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV8zLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfM19tZXRhXzMKYGBgCgpgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzMgPC0gbGlzdCgpCnNpbV9saXN0XzNfbWV0YV8zIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzMgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzMsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zX21ldGFfMyA8LSBvdXRfMTAwXzNfbWV0YV8zJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV8zW1tpXV0gPC0gc2ltX2RhdGFfM19tZXRhXzMKfQoKc2ltX291dHB1dF8zX21ldGFfMyA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzMpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfM19tZXRhXzMgPC0gc2ltX291dHB1dF8zX21ldGFfMyAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzMKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zX21ldGFfMyA8LSBzaW1fb3V0cHV0XzNfbWV0YV8zICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMykKc2ltX3N1bW1hcnlfM19tZXRhXzMKYGBgCgoKCgoKCiMjIyMgNyBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV83IDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfNyRvbWVnYSA8LSAxLzcKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfNyA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzcsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfM19tZXRhXzcgPC0gb3V0XzNfbWV0YV83JGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfNyA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8zX21ldGFfNywgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV83CmBgYAoKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfbWV0YV83IDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfNyA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV83IDwtIHNzYSgKICAgIHgwID0geDBfM19tZXRhLAogICAgYSA9IGFfM19tZXRhLAogICAgbnUgPSBudV8zX21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzNfbWV0YV83LAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzcgPC0gb3V0XzEwMF8zX21ldGFfNyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX21ldGFfN1tbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV83Cn0KCnNpbV9vdXRwdXRfM19tZXRhXzcgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfbWV0YV83KQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV83IDwtIHNpbV9vdXRwdXRfM19tZXRhXzcgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzNfbWV0YV83CgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzcgPC0gc2ltX291dHB1dF8zX21ldGFfNyAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzcpCnNpbV9zdW1tYXJ5XzNfbWV0YV83CmBgYAoKCgojIyMjIDEwIERheXMKCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8xMCA8LSBwYXJtc18zX21ldGEKcGFybXNfM19tZXRhXzEwJG9tZWdhIDwtIDEvMTAKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzNfbWV0YV8xMCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzEwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV8xMCA8LSBvdXRfM19tZXRhXzEwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfMTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzEwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfM19tZXRhXzEwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzEwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMTAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8zX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfM19tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8zX21ldGFfMTAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzEwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzEwIDwtIG91dF8xMDBfM19tZXRhXzEwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV8xMFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8xMAp9CgpzaW1fb3V0cHV0XzNfbWV0YV8xMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzEwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8xMCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8xMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzEwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzEwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTQpCnNpbV9zdW1tYXJ5XzNfbWV0YV8xMApgYGAKCgojIyMjIDIwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfM19tZXRhXzIwIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfMjAkb21lZ2EgPC0gMS8yMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzNfbWV0YV8yMCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzIwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV8yMCA8LSBvdXRfM19tZXRhXzIwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfMjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzIwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfM19tZXRhXzIwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzIwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMjAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8zX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfM19tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8zX21ldGFfMjAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzIwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzIwIDwtIG91dF8xMDBfM19tZXRhXzIwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV8yMFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8yMAp9CgpzaW1fb3V0cHV0XzNfbWV0YV8yMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzIwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8yMCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8yMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzIwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzIwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzIwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMjApCnNpbV9zdW1tYXJ5XzNfbWV0YV8yMApgYGAKCgoKCgoKIyMjIyAzMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8zMCA8LSBwYXJtc18zX21ldGEKcGFybXNfM19tZXRhXzMwJG9tZWdhIDwtIDEvMzAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMzAgPC0gc3NhKAogIHgwID0geDBfM19tZXRhLAogIGEgPSBhXzNfbWV0YSwKICBudSA9IG51XzNfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8zMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfMzAgPC0gb3V0XzNfbWV0YV8zMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfM19tZXRhXzMwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV8zMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8zMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfbWV0YV8zMCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzMwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzMwIDwtIHNzYSgKICAgIHgwID0geDBfM19tZXRhLAogICAgYSA9IGFfM19tZXRhLAogICAgbnUgPSBudV8zX21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8zMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV8zMCA8LSBvdXRfMTAwXzNfbWV0YV8zMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX21ldGFfMzBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfMzAKfQoKc2ltX291dHB1dF8zX21ldGFfMzAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfbWV0YV8zMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfMzAgPC0gc2ltX291dHB1dF8zX21ldGFfMzAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzNfbWV0YV8zMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV8zMCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8zMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLAogICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMzApCnNpbV9zdW1tYXJ5XzNfbWV0YV8zMApgYGAKCgoKIyMjIyA0MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV80MCA8LSBwYXJtc18zX21ldGEKcGFybXNfM19tZXRhXzQwJG9tZWdhIDwtIDEvNDAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfNDAgPC0gc3NhKAogIHgwID0geDBfM19tZXRhLAogIGEgPSBhXzNfbWV0YSwKICBudSA9IG51XzNfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzNfbWV0YV80MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfNDAgPC0gb3V0XzNfbWV0YV80MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfM19tZXRhXzQwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV80MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV80MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfbWV0YV80MCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzQwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzQwIDwtIHNzYSgKICAgIHgwID0geDBfM19tZXRhLAogICAgYSA9IGFfM19tZXRhLAogICAgbnUgPSBudV8zX21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzNfbWV0YV80MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV80MCA8LSBvdXRfMTAwXzNfbWV0YV80MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX21ldGFfNDBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfNDAKfQoKc2ltX291dHB1dF8zX21ldGFfNDAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfbWV0YV80MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfNDAgPC0gc2ltX291dHB1dF8zX21ldGFfNDAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzNfbWV0YV80MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV80MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV80MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzQwKQpzaW1fc3VtbWFyeV8zX21ldGFfNDAKYGBgCgoKCgoKCgojIyMjIDUwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfM19tZXRhXzUwIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfNTAkb21lZ2EgPC0gMS81MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzNfbWV0YV81MCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzUwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV81MCA8LSBvdXRfM19tZXRhXzUwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfNTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzUwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfM19tZXRhXzUwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzUwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfNTAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8zX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfM19tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8zX21ldGFfNTAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzUwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzUwIDwtIG91dF8xMDBfM19tZXRhXzUwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV81MFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV81MAp9CgpzaW1fb3V0cHV0XzNfbWV0YV81MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzUwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV81MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV81MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzUwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzUwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzUwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNTApCnNpbV9zdW1tYXJ5XzNfbWV0YV81MApgYGAKCgoKCgojIyMjIDYwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfM19tZXRhXzYwIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfNjAkb21lZ2EgPC0gMS82MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzNfbWV0YV82MCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzYwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV82MCA8LSBvdXRfM19tZXRhXzYwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfNjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzYwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfM19tZXRhXzYwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzYwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfNjAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8zX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfM19tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8zX21ldGFfNjAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzYwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzYwIDwtIG91dF8xMDBfM19tZXRhXzYwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV82MFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV82MAp9CgpzaW1fb3V0cHV0XzNfbWV0YV82MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzYwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV82MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV82MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzYwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzYwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzYwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNjApCnNpbV9zdW1tYXJ5XzNfbWV0YV82MApgYGAKCgoKCiMjIyMgNzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGFfNzAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV83MCRvbWVnYSA8LSAxLzcwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzcwIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfNzAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfM19tZXRhXzcwIDwtIG91dF8zX21ldGFfNzAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV83MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8zX21ldGFfNzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfNzAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfNzAgPC0gbGlzdCgpCnNpbV9saXN0XzNfbWV0YV83MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV83MCA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfNzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zX21ldGFfNzAgPC0gb3V0XzEwMF8zX21ldGFfNzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzcwW1tpXV0gPC0gc2ltX2RhdGFfM19tZXRhXzcwCn0KCnNpbV9vdXRwdXRfM19tZXRhXzcwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfNzApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfM19tZXRhXzcwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzcwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfNzAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zX21ldGFfNzAgPC0gc2ltX291dHB1dF8zX21ldGFfNzAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS83MCkKc2ltX3N1bW1hcnlfM19tZXRhXzcwCmBgYAoKCiMjIyMgODAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGFfODAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV84MCRvbWVnYSA8LSAxLzgwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzgwIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfODAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfM19tZXRhXzgwIDwtIG91dF8zX21ldGFfODAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV84MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8zX21ldGFfODAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfODAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfODAgPC0gbGlzdCgpCnNpbV9saXN0XzNfbWV0YV84MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV84MCA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfODAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zX21ldGFfODAgPC0gb3V0XzEwMF8zX21ldGFfODAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzgwW1tpXV0gPC0gc2ltX2RhdGFfM19tZXRhXzgwCn0KCnNpbV9vdXRwdXRfM19tZXRhXzgwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfODApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfM19tZXRhXzgwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzgwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfODAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zX21ldGFfODAgPC0gc2ltX291dHB1dF8zX21ldGFfODAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS84MCkKc2ltX3N1bW1hcnlfM19tZXRhXzgwCmBgYAoKCgojIyMjIDkwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfM19tZXRhXzkwIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfOTAkb21lZ2EgPC0gMS85MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzNfbWV0YV85MCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzkwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV85MCA8LSBvdXRfM19tZXRhXzkwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfOTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzkwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfM19tZXRhXzkwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzkwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfOTAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8zX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfM19tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8zX21ldGFfOTAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzkwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzkwIDwtIG91dF8xMDBfM19tZXRhXzkwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV85MFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV85MAp9CgpzaW1fb3V0cHV0XzNfbWV0YV85MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzkwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV85MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV85MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzkwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzkwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzkwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvOTApCnNpbV9zdW1tYXJ5XzNfbWV0YV85MApgYGAKCgoKCgoKCiMjIyMgMTgwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfM19tZXRhXzE4MCA8LSBwYXJtc18zX21ldGEKcGFybXNfM19tZXRhXzE4MCRvbWVnYSA8LSAxLzE4MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoMjApCm91dF8zX21ldGFfMTgwIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfMTgwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV8xODAgPC0gb3V0XzNfbWV0YV8xODAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV8xODAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzE4MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8xODAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfMTgwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMTgwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzE4MCA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfMTgwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzE4MCA8LSBvdXRfMTAwXzNfbWV0YV8xODAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzE4MFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8xODAKfQoKc2ltX291dHB1dF8zX21ldGFfMTgwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfMTgwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8xODAgPC0gc2ltX291dHB1dF8zX21ldGFfMTgwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfMTgwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzE4MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8xODAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xODApCnNpbV9zdW1tYXJ5XzNfbWV0YV8xODAKYGBgCgojIyMjIDExMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8xMTAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8xMTAkb21lZ2EgPC0gMS8xMTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMTEwIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfMTEwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV8xMTAgPC0gb3V0XzNfbWV0YV8xMTAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV8xMTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzExMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8xMTAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfMTEwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMTEwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzExMCA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfMTEwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzExMCA8LSBvdXRfMTAwXzNfbWV0YV8xMTAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzExMFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8xMTAKfQoKc2ltX291dHB1dF8zX21ldGFfMTEwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfMTEwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8xMTAgPC0gc2ltX291dHB1dF8zX21ldGFfMTEwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfMTEwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzExMCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8xMTAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMTApCnNpbV9zdW1tYXJ5XzNfbWV0YV8xMTAKYGBgCgojIyMjIDEyMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8xMjAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8xMjAkb21lZ2EgPC0gMS8xMjAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMTIwIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfMTIwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV8xMjAgPC0gb3V0XzNfbWV0YV8xMjAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV8xMjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzEyMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8xMjAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfMTIwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMTIwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzEyMCA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfMTIwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzEyMCA8LSBvdXRfMTAwXzNfbWV0YV8xMjAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzEyMFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8xMjAKfQoKc2ltX291dHB1dF8zX21ldGFfMTIwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfMTIwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8xMjAgPC0gc2ltX291dHB1dF8zX21ldGFfMTIwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfMTIwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzEyMCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8xMjAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMjApCnNpbV9zdW1tYXJ5XzNfbWV0YV8xMjAKYGBgCgojIyMjIDEzMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8xMzAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8xMzAkb21lZ2EgPC0gMS8xMzAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMTMwIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfMTMwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV8xMzAgPC0gb3V0XzNfbWV0YV8xMzAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV8xMzAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzEzMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8xMzAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfMTMwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMTMwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzEzMCA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfMTMwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzEzMCA8LSBvdXRfMTAwXzNfbWV0YV8xMzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzEzMFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8xMzAKfQoKc2ltX291dHB1dF8zX21ldGFfMTMwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfMTMwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8xMzAgPC0gc2ltX291dHB1dF8zX21ldGFfMTMwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfMTMwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzEzMCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8xMzAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMzApCnNpbV9zdW1tYXJ5XzNfbWV0YV8xMzAKYGBgCgoKCgoKCgoKCgoKCiMjIyMgMTUwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfM19tZXRhXzE1MCA8LSBwYXJtc18zX21ldGEKcGFybXNfM19tZXRhXzE1MCRvbWVnYSA8LSAxLzE1MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzNfbWV0YV8xNTAgPC0gc3NhKAogIHgwID0geDBfM19tZXRhLAogIGEgPSBhXzNfbWV0YSwKICBudSA9IG51XzNfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8xNTAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfM19tZXRhXzE1MCA8LSBvdXRfM19tZXRhXzE1MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfM19tZXRhXzE1MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8zX21ldGFfMTUwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfM19tZXRhXzE1MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfbWV0YV8xNTAgPC0gbGlzdCgpCnNpbV9saXN0XzNfbWV0YV8xNTAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8zX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfM19tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8zX21ldGFfMTUwIDwtIHNzYSgKICAgIHgwID0geDBfM19tZXRhLAogICAgYSA9IGFfM19tZXRhLAogICAgbnUgPSBudV8zX21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8xNTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zX21ldGFfMTUwIDwtIG91dF8xMDBfM19tZXRhXzE1MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX21ldGFfMTUwW1tpXV0gPC0gc2ltX2RhdGFfM19tZXRhXzE1MAp9CgpzaW1fb3V0cHV0XzNfbWV0YV8xNTAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfbWV0YV8xNTApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfM19tZXRhXzE1MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8xNTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzNfbWV0YV8xNTAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zX21ldGFfMTUwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzE1MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzE1MCkKc2ltX3N1bW1hcnlfM19tZXRhXzE1MApgYGAKCgojIyMjIDIyMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8yMjAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8yMjAkb21lZ2EgPC0gMS8yMjAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMjIwIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfMjIwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV8yMjAgPC0gb3V0XzNfbWV0YV8yMjAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV8yMjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzIyMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8yMjAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfMjIwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMjIwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzIyMCA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfMjIwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzIyMCA8LSBvdXRfMTAwXzNfbWV0YV8yMjAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzIyMFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8yMjAKfQoKc2ltX291dHB1dF8zX21ldGFfMjIwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfMjIwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8yMjAgPC0gc2ltX291dHB1dF8zX21ldGFfMjIwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfMjIwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzIyMCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8yMjAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8yMjApCnNpbV9zdW1tYXJ5XzNfbWV0YV8yMjAKYGBgCgoKCgojIyMjIDI3MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8yNzAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8yNzAkb21lZ2EgPC0gMS8yNzAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMjcwIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfMjcwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV8yNzAgPC0gb3V0XzNfbWV0YV8yNzAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV8yNzAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzI3MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8yNzAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfMjcwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMjcwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzI3MCA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfMjcwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzI3MCA8LSBvdXRfMTAwXzNfbWV0YV8yNzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzI3MFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8yNzAKfQoKc2ltX291dHB1dF8zX21ldGFfMjcwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfMjcwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8yNzAgPC0gc2ltX291dHB1dF8zX21ldGFfMjcwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfMjcwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzI3MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8yNzAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8yNzApCnNpbV9zdW1tYXJ5XzNfbWV0YV8yNzAKYGBgCgojIyMjIDM2NSBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8zNjUgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8zNjUkb21lZ2EgPC0gMS8zNjUKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMzY1IDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfMzY1LAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV8zNjUgPC0gb3V0XzNfbWV0YV8zNjUkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV8zNjUgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzM2NSwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8zNjUKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfMzY1IDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMzY1IDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzM2NSA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfMzY1LAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzM2NSA8LSBvdXRfMTAwXzNfbWV0YV8zNjUkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzM2NVtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8zNjUKfQoKc2ltX291dHB1dF8zX21ldGFfMzY1IDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfMzY1KQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8zNjUgPC0gc2ltX291dHB1dF8zX21ldGFfMzY1ICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfMzY1CgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzM2NSA8LSBzaW1fb3V0cHV0XzNfbWV0YV8zNjUgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zNjUpCnNpbV9zdW1tYXJ5XzNfbWV0YV8zNjUKYGBgCgpTaW5nbGUKCgoKCgojIyMjIFJlc3VsdHMKYGBge3J9CndhbmluZ19yZXN1bHRzXzMgPC0gc2ltX3N1bW1hcnlfM19tZXRhICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zX21ldGFfMykgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV83KSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzEwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzIwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzMwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzQwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzUwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzYwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzcwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzgwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzkwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzE4MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV8xMTApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zX21ldGFfMTIwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzEzMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV8xNTApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zX21ldGFfMjIwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzI3MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV8zNjUpICU+JQogIG11dGF0ZShpbW11bml0eV9kdXJhdGlvbiA9IDEvb21lZ2EpICU+JQogIGFycmFuZ2UoaW1tdW5pdHlfZHVyYXRpb24pICU+JQogIG11dGF0ZShtb2RlbCA9ICJtZXRhIiwKICAgICAgICAgcGF0Y2hlcyA9IDMpCgp3cml0ZV9jc3Yod2FuaW5nX3Jlc3VsdHNfMywgZmlsZSA9ICIvVXNlcnMvbWF0dGhld2hveWxlL0dpdGh1Yl9SX3Byb2plY3RzL0h1bnRlcl9HYXRoZXJlcl9tb2RlbHMvd2FuaW5nX3Jlc3VsdHNfMy5jc3YiKQoKd2FuaW5nX3Jlc3VsdHNfMwoKYGBgCgpgYGB7cn0KZ2dwbG90KHdhbmluZ19yZXN1bHRzXzMsIGFlcyhpbW11bml0eV9kdXJhdGlvbiwgc3VtX3BlcnNpc3QpKSArCiAgZ2VvbV9saW5lKCkrCiAgZ2VvbV9wb2ludCgpKwogIHRoZW1lX2J3KCkKYGBgCgoKCgoKCiMjIDE0IE1ldGFwb3B1bGF0aW9uIE1vZGVsIAoKIyMjU2V0LXVwCgpgYGB7cn0KIyBEZWZpbmUgUGFyYW1lbnRlcnMKcGF0Y2hQb3BTaXplXzE0IDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgUGF0Y2ggc2l6ZQpVIDwtIGxlbmd0aChwYXRjaFBvcFNpemVfMTQpICAgICAgICAgICAgICAgICAgICAjIE51bWJlciBvZiBwYXRjaGVzCmluaXRpYWxfaW5mZWN0ZWQgPC0gIGFzLnZlY3RvcihybXVsdGlub20oMSwgMSwgcmVwKDAuNSwgVSkpKSAgICMgSW5pdGlhbCBpbmZlY3RlZCAoaW5pdGlhbCBpbmZlY3RlZCBwYXRjaCByYW5kb21seSBnZW5lcmF0ZWQpCmluaXRpYWxfaW5mZWN0ZWRfcGF0Y2ggPC0gd2hpY2goaW5pdGlhbF9pbmZlY3RlZCA+IDApCnNpbU5hbWUgPC0gIlNJUlMgbWV0YXBvcHVsYXRpb24gbW9kZWwiICAgICAgICMgU2ltdWxhdGlvbiBuYW1lCnRmIDwtIDM2NSozICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEZpbmFsIHRpbWUKCiMgQWd0YSBIdW50ZXItR2F0aGVyZXIgY29udGFjdCByYXRlcwp3aXRoaW5fcG9wX2NvbnRhY3QgPSAxCmJldHdlZW5fcG9wX2NvbnRhY3QgPSAwLjUvVSAgICAgIyBub3JtYWxpc2VkIGJ5IG51bWJlciBvZiBwYXRjaGVzIAoKI0NyZWF0ZSB0aGUgbmFtZWQgaW5pdGlhbCBzdGF0ZSB2ZWN0b3IgZm9yIHRoZSBVLXBhdGNoIHN5c3RlbS4KCngwXzE0X21ldGEgPC0gdW5saXN0KGxhcHBseSgKICBzZXFfbGVuKFUpLCAKICBmdW5jdGlvbihpKXsgCiAgICBjKHBhdGNoUG9wU2l6ZV8xNFtpXSAtIGluaXRpYWxfaW5mZWN0ZWRbaV0sIGluaXRpYWxfaW5mZWN0ZWRbaV0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8xNFtpXSkKICB9CikpCgpuYW1lcyh4MF8xNF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKGkpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIGkpKSkKCgojIERlZmluZSB0aGUgc3RhdGUgY2hhbmdlIG1hdHJpeCBmb3IgYSBzaW5nbGUgcGF0Y2gKbnVfMTRfbWV0YSA8LSBtYXRyaXgoYyggLTEsICAwLCAgMCwgKzEsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsICMgUwogICAgICAgICAgICAgICAgICAgICArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAtMSwgIDAsICAwLCAgMCwgIyBFCiAgICAgICAgICAgICAgICAgICAgICAwLCArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAtMSwgIDAsIC0xLCAjIEkKICAgICAgICAgICAgICAgICAgICAgIDAsICAwLCArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAtMSwgIDAsICMgUiAKICAgICAgICAgICAgICAgICAgICAgIDAsICAwLCAgMCwgIDAsICsxLCAtMSAsLTEsIC0xLCAtMSwgLTEpLCAjIE4KICAgICAgICAgICAgIG5yb3c9NSxieXJvdz1UUlVFKQoKIyBEZWZpbmUgcHJvcGVuc2l0eSBmdW5jdGlvbnMKIyBNYXNzLWFjdGlvbgphXzE0X21ldGEgPC0KICB1bmxpc3QobGFwcGx5KAogICAgc2VxX2xlbihVKSwKICAgIGZ1bmN0aW9uKHBhdGNoKSB7CiAgICAgIGkgPC0gcGF0Y2gKICAgICAgcGF0Y2hlcyA8LSAxOlUKICAgICAgI2ogPC0gaWYgKHBhdGNoID09IDEpIFUgZWxzZSBwYXRjaCAtIDEKICAgICAgb3RoZXJfcGF0Y2hlcyA8LSBwYXRjaGVzWy1pXQogICAgICBwYXRjaF9iZXRhIDwtIGMoKQogICAgICBmb3IoayBpbiAoMTooVS0xKSkpewogICAgICAgIHBhdGNoX2JldGFba10gPSBwYXN0ZTAoIisoYmV0YV8iLCBvdGhlcl9wYXRjaGVzW2tdLGksICIqSSIsIG90aGVyX3BhdGNoZXNba10sICIvTiIsIG90aGVyX3BhdGNoZXNba10sICIpKlMiLCBpKQogICAgICB9CiAgICAgIGMoCiAgICAgICAgcGFzdGUwKCIoYmV0YV8iLCBpLCBpLCAiKkkiLCBpLCIvTiIsIGksICIpKlMiLGksIHBhc3RlMChwYXRjaF9iZXRhLCBjb2xsYXBzZT0iIikpLCAjIEluZmVjdGlvbgogICAgICAgIHBhc3RlMCgic2lnbWEqRSIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQmVjb21lcyBpbmZlY2lvdXMKICAgICAgICBwYXN0ZTAoImdhbW1hKkkiLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIFJlY292ZXJ5IGZyb20gaW5mZWN0aW9uCiAgICAgICAgcGFzdGUwKCJvbWVnYSpSIiwgaSksICAgICAgICMgTG9zcyBvZiBpbW11bml0eQogICAgICAgIHBhc3RlMCgibXUqTiIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBCaXJ0aHMKICAgICAgICBwYXN0ZTAoIm11KlMiLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoUykKICAgICAgICBwYXN0ZTAoIm11KkUiLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoRSkKICAgICAgICBwYXN0ZTAoIm11KkkiLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoSSkKICAgICAgICBwYXN0ZTAoIm11KlIiLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoUikKICAgICAgICBwYXN0ZTAoImFscGhhKkkiLCBpKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyBmcm9tIGluZmVjdGlvbgogICAgICAgIAogICAgICApCiAgICB9CiAgKSkKCmBgYAoKCgojIyMgTWV0YXBvcHVsYXRpb24gTW9kZWwKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTRfbWV0YSA8LSBsaXN0KAogIHNpZ21hID0gMC4xNzUsICAgICAgICAgICAgICAgICAgICAgICAgICAjIEUgdG8gSSByYXRlCiAgZ2FtbWEgPSAwLjIsICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBJIHRvIFIgcmF0ZQogIG9tZWdhID0gMS8xMDAsICAgICAgICAgICAgICAgICAgICAgICAgICMgUiB0byBTIHJhdGUKICBtdSA9IGRlbW9fc3VtJEJpcnRoX3JhdGVfZGFpbHlfTWVhbiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBCaXJ0aC9kZWF0aCByYXRlIHBlciBwZXJzb24gcGVyIGRheQogIGFscGhhID0gMS8xMDAwKSAKCiMgRGVmaW5lIHRyYW5zbWlzc2lvbiB0ZXJtcyBhbmQgcG9wdWxhdGUgbmV4dC1nZW5lcmF0aW9uIG1hdHJpeApiZXRhIDwtIDAuNgoKbmV4dGdlbl8xNF9tYXRyaXggPC0gbWF0cml4KG5yb3cgPSBVLCBuY29sID0gVSwgZGF0YSA9IDApCmJldGFfMTRfbWF0cml4IDwtIG1hdHJpeChucm93ID0gVSwgbmNvbCA9IFUsIGRhdGEgPSAwKQoKCmZvcihpIGluIDE6VSl7CiAgZm9yKGogaW4gMTpVKXsKICAgIHBhcm1zXzE0X21ldGFbW3Bhc3RlMCgiYmV0YV8iLGksaSldXSA9IHdpdGhpbl9wb3BfY29udGFjdCpiZXRhCiAgICBuZXh0Z2VuXzE0X21hdHJpeFtpLGldID0gd2l0aGluX3BvcF9jb250YWN0KmJldGEqKDEvcGFybXNfMTRfbWV0YSRnYW1tYSkKICAgIHBhcm1zXzE0X21ldGFbW3Bhc3RlMCgiYmV0YV8iLGosaSldXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YQogICAgbmV4dGdlbl8xNF9tYXRyaXhbaixpXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YSooMS9wYXJtc18xNF9tZXRhJGdhbW1hKQogICAgbmV4dGdlbl8xNF9tYXRyaXhbaSxqXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YSooMS9wYXJtc18xNF9tZXRhJGdhbW1hKQogICAgcGFybXNfMTRfbWV0YVtbcGFzdGUwKCJiZXRhXyIsaixqKV1dID0gd2l0aGluX3BvcF9jb250YWN0KmJldGEKICAgIG5leHRnZW5fMTRfbWF0cml4W2osal0gPSB3aXRoaW5fcG9wX2NvbnRhY3QqYmV0YSooMS9wYXJtc18xNF9tZXRhJGdhbW1hKQogICAgYmV0YV8xNF9tYXRyaXhbaSxpXSA9IHdpdGhpbl9wb3BfY29udGFjdCpiZXRhCiAgICBiZXRhXzE0X21hdHJpeFtqLGldID0gYmV0d2Vlbl9wb3BfY29udGFjdCpiZXRhCiAgICBiZXRhXzE0X21hdHJpeFtpLGpdID0gYmV0d2Vlbl9wb3BfY29udGFjdCpiZXRhCiAgICBiZXRhXzE0X21hdHJpeFtqLGpdID0gd2l0aGluX3BvcF9jb250YWN0KmJldGEKICB9CiAgcGFybXNfMTRfbWV0YVtbcGFzdGUwKCJOIiwgaSldXSA9IHBhdGNoUG9wU2l6ZV8xNFtpXQp9CmBgYAoKCmBgYHtyfQojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDI1KQpvdXRfMTRfbWV0YSA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YSwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIFBsb3QKcGxvdF9kYXRhXzE0X21ldGEgPC0gb3V0XzE0X21ldGEkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGEgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YSwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKGFscGhhPTAuOCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDEsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUgKERheXMpIiwKICAgICAgIHk9Ik51bWJlciBvZiBJbmRpdmlkdWFscyIsCiAgICAgICBjb2xvdXI9IlN0YXRlIikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGEKCmdnc2F2ZShmaWxlbmFtZSA9ICJtZXRhXzE0X3Bsb3QucGRmIiwgCiAgICAgICBwbG90ID0gcGxvdF8xNF9tZXRhLAogICAgICAgZGV2aWNlID0gInBkZiIsCiAgICAgICB3aWR0aCA9IDcsIAogICAgICAgaGVpZ2h0ID0gOCwKICAgICAgIHBhdGggPSAiL1VzZXJzL21hdHRoZXdob3lsZS9HaXRodWJfUl9wcm9qZWN0cy9IdW50ZXJfR2F0aGVyZXJfbW9kZWxzIikKYGBgCgpgYGB7cn0KIyMgVGFibGUgc2hvd2luZyBleHRpbmN0aW9uL3RyYW5zbWlzc2lvbiBpbmZvIGZvciBlYWNoIHBhdGNoCgpleHRpbmN0X2RhdGFfMTRfbWV0YSA8LSBvdXRfMTRfbWV0YSRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHNsaWNlX21heCh0KSAlPiUKICBkaXN0aW5jdCgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSksCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4oc3RhdGU9PSJJIiAmIGNvdW50ID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlPT0iSSIgJiBjb3VudCA9PSAwIH4gRikpICU+JQogIGRyb3BfbmEoKSAlPiUKICBzZWxlY3QocGF0Y2gsIGNvdW50LCBwZXJzaXN0KQpleHRpbmN0X2RhdGFfMTRfbWV0YQpgYGAKCgpgYGB7cn0KYmV0YV8xNF9tZXRhIDwtIGJldGEubmdtKGJldGFfMTRfbWF0cml4KQpwYXN0ZTAoIkJldGEgZm9yIHdob2xlIHN5c3RlbSA9ICIsIGJldGFfMTRfbWV0YSkKCgpSMF8xNF9tZXRhIDwtIFIwbmdtKG5leHRnZW5fMTRfbWF0cml4KQpwYXN0ZTAoIlIwID0gIiwgUjBfMTRfbWV0YSkKCgpwYXN0ZTAoIkFjdHVhbCBudW1iZXIgb2YgaW5mZWN0ZWRzIGF0IGVuZCBvZiBzaW0gPSAiLCBzdW0oZXh0aW5jdF9kYXRhXzE0X21ldGEkY291bnQpKQogIyBUb3RhbCBudW1iZXIgb2YgaW5mZWN0ZWRzIGF0IHRoZSBlbmQgb2Ygc2ltIGFjcm9zcyBhbGwgcGF0Y2hlcwoKc2ltX2VuZHBvaW50XzE0X21ldGEgPC0gYXNfdGliYmxlKG91dF8xNF9tZXRhJGRhdGEpICU+JQogIHNsaWNlX21heCh0KSAlPiUKICBkaXN0aW5jdCgpCgoKcGFzdGUwKCJEaWQgc2ltdWxhdGlvbiBydW4gcmVhY2ggZmluYWwgZW5kcG9pbnQ/IikKaWYgKHNpbV9lbmRwb2ludF8xNF9tZXRhJHQgPj0gdGYpIHsKICBwcmludCgiWWVzIikKfSBlbHNlIHsKICBwcmludCgiTm8iKX0KCmBgYAoKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE0X21ldGEgPC0gbGlzdCgpCnNpbV9saXN0XzE0X21ldGEgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMTQgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KGxhcHBseSgKICBzZXFfbGVuKFUpLCAKICBmdW5jdGlvbih4KXsgCiAgICBjKHBhdGNoUG9wU2l6ZV8xNFt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8xNFt4XSkKICB9CikpCgpuYW1lcyh4MF8xNF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKICAKICBvdXRfMTAwXzE0X21ldGEgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YSwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGEgPC0gb3V0XzEwMF8xNF9tZXRhJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhCn0KCnNpbV9vdXRwdXRfMTRfbWV0YSA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhIDwtIHNpbV9vdXRwdXRfMTRfbWV0YSAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YQpgYGAKCgoKYGBge3J9CiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNF9tZXRhIDwtIHNpbV9vdXRwdXRfMTRfbWV0YSAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLAogICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTAwKQpzaW1fc3VtbWFyeV8xNF9tZXRhCmBgYAoKIyMjIFZhcnlpbmcgd2FpbmluZyBpbW11bml0eQojIyMjIDAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzAgPC0gcGFybXNfMTRfbWV0YQpwYXJtc18xNF9tZXRhXzAkb21lZ2EgPC0gMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzE0X21ldGFfMCA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YV8wLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfMCA8LSBvdXRfMTRfbWV0YV8wJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhXzAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV8wLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMTRfbWV0YV8wCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTRfbWV0YV8wIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfMTRfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8xNF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8xNF9tZXRhXzAgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YV8wLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV8wIDwtIG91dF8xMDBfMTRfbWV0YV8wJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFfMFtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfMAp9CgpzaW1fb3V0cHV0XzE0X21ldGFfMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YV8wKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfMCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YV8wCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YV8wIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8wICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsCiAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMCkKc2ltX3N1bW1hcnlfMTRfbWV0YV8wCmBgYAoKCiMjIyMgMTAgRGF5cwoKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTRfbWV0YV8xMCA8LSBwYXJtc18xNF9tZXRhCnBhcm1zXzE0X21ldGFfMTAkb21lZ2EgPC0gMS8xMAoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTRfbWV0YV8xMCA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YV8xMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNF9tZXRhXzEwIDwtIG91dF8xNF9tZXRhXzEwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhXzEwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGFfMTAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzEwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTRfbWV0YV8xMCA8LSBsaXN0KCkKc2ltX2xpc3RfMTRfbWV0YV8xMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfMTAgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YV8xMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGFfMTAgPC0gb3V0XzEwMF8xNF9tZXRhXzEwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFfMTBbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhXzEwCn0KCnNpbV9vdXRwdXRfMTRfbWV0YV8xMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YV8xMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhXzEwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8xMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YV8xMCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMTAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMCkKc2ltX3N1bW1hcnlfMTRfbWV0YV8xMApgYGAKCgojIyMjIDIwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTRfbWV0YV8yMCA8LSBwYXJtc18xNF9tZXRhCnBhcm1zXzE0X21ldGFfMjAkb21lZ2EgPC0gMS8yMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzE0X21ldGFfMjAgPC0gc3NhKAogIHgwID0geDBfMTRfbWV0YSwKICBhID0gYV8xNF9tZXRhLAogIG51ID0gbnVfMTRfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMjAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTRfbWV0YV8yMCA8LSBvdXRfMTRfbWV0YV8yMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMTRfbWV0YV8yMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xNF9tZXRhXzIwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMTRfbWV0YV8yMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE0X21ldGFfMjAgPC0gbGlzdCgpCnNpbV9saXN0XzE0X21ldGFfMjAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfMTRfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8xNF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8xNF9tZXRhXzIwIDwtIHNzYSgKICAgIHgwID0geDBfMTRfbWV0YSwKICAgIGEgPSBhXzE0X21ldGEsCiAgICBudSA9IG51XzE0X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMjAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNF9tZXRhXzIwIDwtIG91dF8xMDBfMTRfbWV0YV8yMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNF9tZXRhXzIwW1tpXV0gPC0gc2ltX2RhdGFfMTRfbWV0YV8yMAp9CgpzaW1fb3V0cHV0XzE0X21ldGFfMjAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE0X21ldGFfMjApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTRfbWV0YV8yMCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMjAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE0X21ldGFfMjAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNF9tZXRhXzIwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8yMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzIwKQpzaW1fc3VtbWFyeV8xNF9tZXRhXzIwCmBgYAoKCgoKCgojIyMjIDMwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTRfbWV0YV8zMCA8LSBwYXJtc18xNF9tZXRhCnBhcm1zXzE0X21ldGFfMzAkb21lZ2EgPC0gMS8zMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzE0X21ldGFfMzAgPC0gc3NhKAogIHgwID0geDBfMTRfbWV0YSwKICBhID0gYV8xNF9tZXRhLAogIG51ID0gbnVfMTRfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMzAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTRfbWV0YV8zMCA8LSBvdXRfMTRfbWV0YV8zMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMTRfbWV0YV8zMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xNF9tZXRhXzMwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMTRfbWV0YV8zMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE0X21ldGFfMzAgPC0gbGlzdCgpCnNpbV9saXN0XzE0X21ldGFfMzAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfMTRfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8xNF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8xNF9tZXRhXzMwIDwtIHNzYSgKICAgIHgwID0geDBfMTRfbWV0YSwKICAgIGEgPSBhXzE0X21ldGEsCiAgICBudSA9IG51XzE0X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNF9tZXRhXzMwIDwtIG91dF8xMDBfMTRfbWV0YV8zMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNF9tZXRhXzMwW1tpXV0gPC0gc2ltX2RhdGFfMTRfbWV0YV8zMAp9CgpzaW1fb3V0cHV0XzE0X21ldGFfMzAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE0X21ldGFfMzApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTRfbWV0YV8zMCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMzAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE0X21ldGFfMzAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNF9tZXRhXzMwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8zMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLAogICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMzApCnNpbV9zdW1tYXJ5XzE0X21ldGFfMzAKYGBgCgoKCiMjIyMgNDAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzQwIDwtIHBhcm1zXzE0X21ldGEKcGFybXNfMTRfbWV0YV80MCRvbWVnYSA8LSAxLzQwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTRfbWV0YV80MCA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YV80MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNF9tZXRhXzQwIDwtIG91dF8xNF9tZXRhXzQwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhXzQwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGFfNDAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzQwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTRfbWV0YV80MCA8LSBsaXN0KCkKc2ltX2xpc3RfMTRfbWV0YV80MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfNDAgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YV80MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGFfNDAgPC0gb3V0XzEwMF8xNF9tZXRhXzQwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFfNDBbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhXzQwCn0KCnNpbV9vdXRwdXRfMTRfbWV0YV80MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YV80MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhXzQwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV80MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YV80MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE0X21ldGFfNDAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzQwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNDApCnNpbV9zdW1tYXJ5XzE0X21ldGFfNDAKYGBgCgoKCgoKCgojIyMjIDUwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTRfbWV0YV81MCA8LSBwYXJtc18xNF9tZXRhCnBhcm1zXzE0X21ldGFfNTAkb21lZ2EgPC0gMS81MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzE0X21ldGFfNTAgPC0gc3NhKAogIHgwID0geDBfMTRfbWV0YSwKICBhID0gYV8xNF9tZXRhLAogIG51ID0gbnVfMTRfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfNTAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTRfbWV0YV81MCA8LSBvdXRfMTRfbWV0YV81MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMTRfbWV0YV81MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xNF9tZXRhXzUwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMTRfbWV0YV81MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE0X21ldGFfNTAgPC0gbGlzdCgpCnNpbV9saXN0XzE0X21ldGFfNTAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfMTRfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8xNF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8xNF9tZXRhXzUwIDwtIHNzYSgKICAgIHgwID0geDBfMTRfbWV0YSwKICAgIGEgPSBhXzE0X21ldGEsCiAgICBudSA9IG51XzE0X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfNTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNF9tZXRhXzUwIDwtIG91dF8xMDBfMTRfbWV0YV81MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNF9tZXRhXzUwW1tpXV0gPC0gc2ltX2RhdGFfMTRfbWV0YV81MAp9CgpzaW1fb3V0cHV0XzE0X21ldGFfNTAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE0X21ldGFfNTApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTRfbWV0YV81MCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfNTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE0X21ldGFfNTAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNF9tZXRhXzUwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV81MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzUwKQpzaW1fc3VtbWFyeV8xNF9tZXRhXzUwCmBgYAoKCgoKCiMjIyMgNjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzYwIDwtIHBhcm1zXzE0X21ldGEKcGFybXNfMTRfbWV0YV82MCRvbWVnYSA8LSAxLzYwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTRfbWV0YV82MCA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YV82MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNF9tZXRhXzYwIDwtIG91dF8xNF9tZXRhXzYwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhXzYwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGFfNjAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzYwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTRfbWV0YV82MCA8LSBsaXN0KCkKc2ltX2xpc3RfMTRfbWV0YV82MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfNjAgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YV82MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGFfNjAgPC0gb3V0XzEwMF8xNF9tZXRhXzYwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFfNjBbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhXzYwCn0KCnNpbV9vdXRwdXRfMTRfbWV0YV82MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YV82MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhXzYwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV82MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YV82MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE0X21ldGFfNjAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzYwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNjApCnNpbV9zdW1tYXJ5XzE0X21ldGFfNjAKYGBgCgoKCgojIyMjIDcwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTRfbWV0YV83MCA8LSBwYXJtc18xNF9tZXRhCnBhcm1zXzE0X21ldGFfNzAkb21lZ2EgPC0gMS83MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzE0X21ldGFfNzAgPC0gc3NhKAogIHgwID0geDBfMTRfbWV0YSwKICBhID0gYV8xNF9tZXRhLAogIG51ID0gbnVfMTRfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfNzAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTRfbWV0YV83MCA8LSBvdXRfMTRfbWV0YV83MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMTRfbWV0YV83MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xNF9tZXRhXzcwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMTRfbWV0YV83MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE0X21ldGFfNzAgPC0gbGlzdCgpCnNpbV9saXN0XzE0X21ldGFfNzAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfMTRfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8xNF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8xNF9tZXRhXzcwIDwtIHNzYSgKICAgIHgwID0geDBfMTRfbWV0YSwKICAgIGEgPSBhXzE0X21ldGEsCiAgICBudSA9IG51XzE0X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfNzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNF9tZXRhXzcwIDwtIG91dF8xMDBfMTRfbWV0YV83MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNF9tZXRhXzcwW1tpXV0gPC0gc2ltX2RhdGFfMTRfbWV0YV83MAp9CgpzaW1fb3V0cHV0XzE0X21ldGFfNzAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE0X21ldGFfNzApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTRfbWV0YV83MCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfNzAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE0X21ldGFfNzAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNF9tZXRhXzcwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV83MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzcwKQpzaW1fc3VtbWFyeV8xNF9tZXRhXzcwCmBgYAoKCiMjIyMgODAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzgwIDwtIHBhcm1zXzE0X21ldGEKcGFybXNfMTRfbWV0YV84MCRvbWVnYSA8LSAxLzgwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTRfbWV0YV84MCA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YV84MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNF9tZXRhXzgwIDwtIG91dF8xNF9tZXRhXzgwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhXzgwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGFfODAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzgwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTRfbWV0YV84MCA8LSBsaXN0KCkKc2ltX2xpc3RfMTRfbWV0YV84MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfODAgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YV84MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGFfODAgPC0gb3V0XzEwMF8xNF9tZXRhXzgwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFfODBbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhXzgwCn0KCnNpbV9vdXRwdXRfMTRfbWV0YV84MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YV84MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhXzgwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV84MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YV84MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE0X21ldGFfODAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzgwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvODApCnNpbV9zdW1tYXJ5XzE0X21ldGFfODAKYGBgCgoKCiMjIyMgOTAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzkwIDwtIHBhcm1zXzE0X21ldGEKcGFybXNfMTRfbWV0YV85MCRvbWVnYSA8LSAxLzkwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTRfbWV0YV85MCA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YV85MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNF9tZXRhXzkwIDwtIG91dF8xNF9tZXRhXzkwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhXzkwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGFfOTAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzkwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTRfbWV0YV85MCA8LSBsaXN0KCkKc2ltX2xpc3RfMTRfbWV0YV85MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfOTAgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YV85MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGFfOTAgPC0gb3V0XzEwMF8xNF9tZXRhXzkwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFfOTBbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhXzkwCn0KCnNpbV9vdXRwdXRfMTRfbWV0YV85MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YV85MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhXzkwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV85MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YV85MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE0X21ldGFfOTAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzkwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvOTApCnNpbV9zdW1tYXJ5XzE0X21ldGFfOTAKYGBgCgoKCgoKCgojIyMjIDE4MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGFfMTgwIDwtIHBhcm1zXzE0X21ldGEKcGFybXNfMTRfbWV0YV8xODAkb21lZ2EgPC0gMS8xODAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDIwKQpvdXRfMTRfbWV0YV8xODAgPC0gc3NhKAogIHgwID0geDBfMTRfbWV0YSwKICBhID0gYV8xNF9tZXRhLAogIG51ID0gbnVfMTRfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMTgwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfMTgwIDwtIG91dF8xNF9tZXRhXzE4MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMTRfbWV0YV8xODAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV8xODAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzE4MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE0X21ldGFfMTgwIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzE4MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfMTgwIDwtIHNzYSgKICAgIHgwID0geDBfMTRfbWV0YSwKICAgIGEgPSBhXzE0X21ldGEsCiAgICBudSA9IG51XzE0X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMTgwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV8xODAgPC0gb3V0XzEwMF8xNF9tZXRhXzE4MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNF9tZXRhXzE4MFtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfMTgwCn0KCnNpbV9vdXRwdXRfMTRfbWV0YV8xODAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE0X21ldGFfMTgwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfMTgwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8xODAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE0X21ldGFfMTgwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YV8xODAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzE4MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzE4MCkKc2ltX3N1bW1hcnlfMTRfbWV0YV8xODAKYGBgCgojIyMjIDExMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGFfMTEwIDwtIHBhcm1zXzE0X21ldGEKcGFybXNfMTRfbWV0YV8xMTAkb21lZ2EgPC0gMS8xMTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNF9tZXRhXzExMCA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YV8xMTAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTRfbWV0YV8xMTAgPC0gb3V0XzE0X21ldGFfMTEwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhXzExMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xNF9tZXRhXzExMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfMTEwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTRfbWV0YV8xMTAgPC0gbGlzdCgpCnNpbV9saXN0XzE0X21ldGFfMTEwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV8xMTAgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YV8xMTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNF9tZXRhXzExMCA8LSBvdXRfMTAwXzE0X21ldGFfMTEwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFfMTEwW1tpXV0gPC0gc2ltX2RhdGFfMTRfbWV0YV8xMTAKfQoKc2ltX291dHB1dF8xNF9tZXRhXzExMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YV8xMTApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTRfbWV0YV8xMTAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzExMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YV8xMTAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNF9tZXRhXzExMCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMTEwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTEwKQpzaW1fc3VtbWFyeV8xNF9tZXRhXzExMApgYGAKCiMjIyMgMTIwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTRfbWV0YV8xMjAgPC0gcGFybXNfMTRfbWV0YQpwYXJtc18xNF9tZXRhXzEyMCRvbWVnYSA8LSAxLzEyMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzE0X21ldGFfMTIwIDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzEyMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNF9tZXRhXzEyMCA8LSBvdXRfMTRfbWV0YV8xMjAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfMTIwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGFfMTIwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMTRfbWV0YV8xMjAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzEyMCA8LSBsaXN0KCkKc2ltX2xpc3RfMTRfbWV0YV8xMjAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfMTRfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8xNF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8xNF9tZXRhXzEyMCA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzEyMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGFfMTIwIDwtIG91dF8xMDBfMTRfbWV0YV8xMjAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV8xMjBbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhXzEyMAp9CgpzaW1fb3V0cHV0XzE0X21ldGFfMTIwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzEyMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhXzEyMCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMTIwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNF9tZXRhXzEyMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE0X21ldGFfMTIwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8xMjAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMjApCnNpbV9zdW1tYXJ5XzE0X21ldGFfMTIwCmBgYAoKIyMjIyAxMzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzEzMCA8LSBwYXJtc18xNF9tZXRhCnBhcm1zXzE0X21ldGFfMTMwJG9tZWdhIDwtIDEvMTMwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTRfbWV0YV8xMzAgPC0gc3NhKAogIHgwID0geDBfMTRfbWV0YSwKICBhID0gYV8xNF9tZXRhLAogIG51ID0gbnVfMTRfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMTMwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfMTMwIDwtIG91dF8xNF9tZXRhXzEzMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMTRfbWV0YV8xMzAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV8xMzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzEzMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE0X21ldGFfMTMwIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzEzMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfMTMwIDwtIHNzYSgKICAgIHgwID0geDBfMTRfbWV0YSwKICAgIGEgPSBhXzE0X21ldGEsCiAgICBudSA9IG51XzE0X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMTMwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV8xMzAgPC0gb3V0XzEwMF8xNF9tZXRhXzEzMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNF9tZXRhXzEzMFtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfMTMwCn0KCnNpbV9vdXRwdXRfMTRfbWV0YV8xMzAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE0X21ldGFfMTMwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfMTMwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8xMzAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE0X21ldGFfMTMwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YV8xMzAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzEzMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEzMCkKc2ltX3N1bW1hcnlfMTRfbWV0YV8xMzAKYGBgCgoKCgoKCgoKCgoKCiMjIyMgMTUwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTRfbWV0YV8xNTAgPC0gcGFybXNfMTRfbWV0YQpwYXJtc18xNF9tZXRhXzE1MCRvbWVnYSA8LSAxLzE1MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzE0X21ldGFfMTUwIDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzE1MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNF9tZXRhXzE1MCA8LSBvdXRfMTRfbWV0YV8xNTAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfMTUwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGFfMTUwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMTRfbWV0YV8xNTAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzE1MCA8LSBsaXN0KCkKc2ltX2xpc3RfMTRfbWV0YV8xNTAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfMTRfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8xNF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8xNF9tZXRhXzE1MCA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzE1MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGFfMTUwIDwtIG91dF8xMDBfMTRfbWV0YV8xNTAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV8xNTBbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhXzE1MAp9CgpzaW1fb3V0cHV0XzE0X21ldGFfMTUwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzE1MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhXzE1MCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMTUwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNF9tZXRhXzE1MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE0X21ldGFfMTUwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8xNTAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xNTApCnNpbV9zdW1tYXJ5XzE0X21ldGFfMTUwCmBgYAoKCiMjIyMgMjIwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTRfbWV0YV8yMjAgPC0gcGFybXNfMTRfbWV0YQpwYXJtc18xNF9tZXRhXzIyMCRvbWVnYSA8LSAxLzIyMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzE0X21ldGFfMjIwIDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzIyMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNF9tZXRhXzIyMCA8LSBvdXRfMTRfbWV0YV8yMjAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfMjIwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGFfMjIwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMTRfbWV0YV8yMjAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzIyMCA8LSBsaXN0KCkKc2ltX2xpc3RfMTRfbWV0YV8yMjAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfMTRfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8xNF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8xNF9tZXRhXzIyMCA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzIyMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGFfMjIwIDwtIG91dF8xMDBfMTRfbWV0YV8yMjAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV8yMjBbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhXzIyMAp9CgpzaW1fb3V0cHV0XzE0X21ldGFfMjIwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzIyMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhXzIyMCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMjIwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNF9tZXRhXzIyMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE0X21ldGFfMjIwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8yMjAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8yMjApCnNpbV9zdW1tYXJ5XzE0X21ldGFfMjIwCmBgYAoKCgoKIyMjIyAyNzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzI3MCA8LSBwYXJtc18xNF9tZXRhCnBhcm1zXzE0X21ldGFfMjcwJG9tZWdhIDwtIDEvMjcwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTRfbWV0YV8yNzAgPC0gc3NhKAogIHgwID0geDBfMTRfbWV0YSwKICBhID0gYV8xNF9tZXRhLAogIG51ID0gbnVfMTRfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMjcwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfMjcwIDwtIG91dF8xNF9tZXRhXzI3MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMTRfbWV0YV8yNzAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV8yNzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzI3MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE0X21ldGFfMjcwIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzI3MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfMjcwIDwtIHNzYSgKICAgIHgwID0geDBfMTRfbWV0YSwKICAgIGEgPSBhXzE0X21ldGEsCiAgICBudSA9IG51XzE0X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMjcwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV8yNzAgPC0gb3V0XzEwMF8xNF9tZXRhXzI3MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNF9tZXRhXzI3MFtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfMjcwCn0KCnNpbV9vdXRwdXRfMTRfbWV0YV8yNzAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE0X21ldGFfMjcwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfMjcwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8yNzAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE0X21ldGFfMjcwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YV8yNzAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzI3MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzI3MCkKc2ltX3N1bW1hcnlfMTRfbWV0YV8yNzAKYGBgCgojIyMjIDM2NSBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGFfMzY1IDwtIHBhcm1zXzE0X21ldGEKcGFybXNfMTRfbWV0YV8zNjUkb21lZ2EgPC0gMS8zNjUKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNF9tZXRhXzM2NSA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YV8zNjUsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTRfbWV0YV8zNjUgPC0gb3V0XzE0X21ldGFfMzY1JGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhXzM2NSA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xNF9tZXRhXzM2NSwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfMzY1CmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTRfbWV0YV8zNjUgPC0gbGlzdCgpCnNpbV9saXN0XzE0X21ldGFfMzY1IDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV8zNjUgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YV8zNjUsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNF9tZXRhXzM2NSA8LSBvdXRfMTAwXzE0X21ldGFfMzY1JGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFfMzY1W1tpXV0gPC0gc2ltX2RhdGFfMTRfbWV0YV8zNjUKfQoKc2ltX291dHB1dF8xNF9tZXRhXzM2NSA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YV8zNjUpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTRfbWV0YV8zNjUgPC0gc2ltX291dHB1dF8xNF9tZXRhXzM2NSAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YV8zNjUKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNF9tZXRhXzM2NSA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMzY1ICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMzY1KQpzaW1fc3VtbWFyeV8xNF9tZXRhXzM2NQpgYGAKCgoKCgojIyMjIFJlc3VsdHMKYGBge3J9CndhbmluZ19yZXN1bHRzXzE0IDwtIHNpbV9zdW1tYXJ5XzE0X21ldGEgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE0X21ldGFfMTApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNF9tZXRhXzIwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTRfbWV0YV8zMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE0X21ldGFfNDApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNF9tZXRhXzUwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTRfbWV0YV82MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE0X21ldGFfNzApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNF9tZXRhXzgwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTRfbWV0YV85MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE0X21ldGFfMTgwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTRfbWV0YV8xMTApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNF9tZXRhXzEyMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE0X21ldGFfMTMwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTRfbWV0YV8xNTApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNF9tZXRhXzIyMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE0X21ldGFfMjcwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTRfbWV0YV8zNjUpICU+JQogIG11dGF0ZShpbW11bml0eV9kdXJhdGlvbiA9IDEvb21lZ2EpICU+JQogIGFycmFuZ2UoaW1tdW5pdHlfZHVyYXRpb24pICU+JQogIG11dGF0ZShtb2RlbCA9ICJtZXRhIiwKICAgICAgICAgcGF0Y2hlcyA9IDE0KQoKd3JpdGVfY3N2KHdhbmluZ19yZXN1bHRzXzE0LCBmaWxlID0gIi9Vc2Vycy9tYXR0aGV3aG95bGUvR2l0aHViX1JfcHJvamVjdHMvSHVudGVyX0dhdGhlcmVyX21vZGVscy93YW5pbmdfcmVzdWx0c18xNC5jc3YiKQoKd2FuaW5nX3Jlc3VsdHNfMTQKCmBgYAoKYGBge3J9CmdncGxvdCh3YW5pbmdfcmVzdWx0c18xNCwgYWVzKGltbXVuaXR5X2R1cmF0aW9uLCBzdW1fcGVyc2lzdCkpICsKICBnZW9tX2xpbmUoKSsKICBnZW9tX3BvaW50KCkrCiAgdGhlbWVfYncoKQpgYGAKCgojIyBDb21iaW5lZCBSZXN1bHRzCmBgYHtyfQojY29tYmluZWRfd2FuaW5nIDwtIHdhbmluZ19yZXN1bHRzICU+JQogICNiaW5kX3Jvd3Mod2FuaW5nX3Jlc3VsdHNfc2luZ2xlKQoKI2NvbWJpbmVkX3dhbmluZwoKCiNjb21iaW5lZF93YW5pbmcgPC0gcmVhZF9jc3YoImNvbWJpbmVkX3dhbmluZ19yZXN1bHRzLmNzdiIpICU+JQogICNtdXRhdGUocGF0Y2hlcyA9IGNhc2Vfd2hlbihtb2RlbCA9PSAibWV0YSIgfiA3LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICNtb2RlbCA9PSAic2luZ2xlIiB+IDEpKSAlPiUKICAjYmluZF9yb3dzKHdhbmluZ19yZXN1bHRzXzE0KQoKI3dyaXRlX2Nzdihjb21iaW5lZF93YW5pbmcsIGZpbGUgPSAiL1VzZXJzL21hdHRoZXdob3lsZS9HaXRodWJfUl9wcm9qZWN0cy9IdW50ZXJfR2F0aGVyZXJfbW9kZWxzL2NvbWJpbmVkX3dhbmluZ19yZXN1bHRzLmNzdiIpCgpgYGAKCgpgYGB7cn0KY29tYmluZWRfcGxvdCA8LSBnZ3Bsb3QoY29tYmluZWRfd2FuaW5nLCBhZXMoaW1tdW5pdHlfZHVyYXRpb24sIHN1bV9wZXJzaXN0LCBjb2xvdXIgPSBhcy5mYWN0b3IocGF0Y2hlcykpKSsKICBnZW9tX2xpbmUoYWxwaGE9MC43LCBzaXplPTEpKwogIGdlb21fcG9pbnQoYWxwaGE9MC41LCBzaXplPTIpKwogIGdlb21fc2VnbWVudCh4ID0gLUluZiwgeSA9IDUwLCB4ZW5kID0gMTQxLjUsIHllbmQgPSA1MCwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3VyID0gImdyZXkiKSArCiAgZ2VvbV9zZWdtZW50KHggPSA1LCB5ID0gNTAsIHhlbmQgPSA1LCB5ZW5kID0gLUluZiwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3VyID0gImdyZXkiKSArCiAgZ2VvbV9zZWdtZW50KHggPSA0Mi41LCB5ID0gNTAsIHhlbmQgPSA0Mi41LCB5ZW5kID0gLUluZiwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3VyID0gImdyZXkiKSArCiAgZ2VvbV9zZWdtZW50KHggPSA5MS41LCB5ID0gNTAsIHhlbmQgPSA5MS41LCB5ZW5kID0gLUluZiwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3VyID0gImdyZXkiKSArCiAgZ2VvbV9zZWdtZW50KHggPSAxNDEuNSwgeSA9IDUwLCB4ZW5kID0gMTQxLjUsIHllbmQgPSAtSW5mLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvdXIgPSAiZ3JleSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDEwMCwgMTApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCAzNjAsIDUwKSkgKwogIGxhYnMoeCA9ICJEdXJhdGlvbiBvZiBpbW11bml0eSAoZGF5cykiLAogICAgICAgeSA9ICJQcm9iYWJpbGl0eSBvZiBwZXJzaXN0ZW5jZSBhZnRlciAzIHllYXJzICglKSIsIAogICAgICAgY29sb3VyID0gIk5vLiBQYXRjaGVzIikrCiAgc2NhbGVfY29sb3JfZGlzY3JldGUodHlwZSA9IHdlc19wYWxldHRlcyRaaXNzb3UxWzI6NV0sCiAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiMSIsICIzIiwgIjciLCAiMTQiKSkrCiAgdGhlbWVfYncoKQoKY29tYmluZWRfcGxvdAoKZ2dzYXZlKGZpbGVuYW1lID0gImNvbWJpbmVkX3Bsb3RfcGF0Y2hlcy5wZGYiLCBwbG90ID0gY29tYmluZWRfcGxvdCwgZGV2aWNlID0gInBkZiIsIHdpZHRoID0gNywgaGVpZ2h0ID0gNSwgcGF0aCA9ICIvVXNlcnMvbWF0dGhld2hveWxlL0dpdGh1Yl9SX3Byb2plY3RzL0h1bnRlcl9HYXRoZXJlcl9tb2RlbHMiKQpgYGAKCmBgYHtyfQpnZ3Bsb3QoY29tYmluZWRfd2FuaW5nLCBhZXMoaW1tdW5pdHlfZHVyYXRpb24sIG1lYW5fcGVyY2VudF9pbmZlY3RlZCwgY29sb3VyID0gYXMuZmFjdG9yKHBhdGNoZXMpKSkrCiAgZ2VvbV9saW5lKCkrCiAgZ2VvbV9wb2ludCgpICsKICBsYWJzKHggPSAiRHVyYXRpb24gb2YgaW1tdW5pdHkiLAogICAgICAgeSA9ICJQcm9wb3J0aW9uIGluZmVjdGVkIGF0IGVuZHBvaW50ICglKSIsIAogICAgICAgY29sb3VyID0gIk1vZGVsIFR5cGUiKSsKICBzY2FsZV9jb2xvcl9kaXNjcmV0ZSh0eXBlID0gd2VzX3BhbGV0dGUoIkRhcmplZWxpbmcxIiwgdHlwZSA9ICJkaXNjcmV0ZSIpWzE6Ml0sCiAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiTWV0YXBvcHVsYXRpb24iLCAiU2luZ2xlIFBvcHVsYXRpb24iKSkrCiAgdGhlbWVfYncoKQpgYGAKCg==